diff --git a/hecl/extern/Athena b/hecl/extern/Athena index ca0ff0434..b317ac9d9 160000 --- a/hecl/extern/Athena +++ b/hecl/extern/Athena @@ -1 +1 @@ -Subproject commit ca0ff04340bd6a25eed1e738e6d976d4a10acf31 +Subproject commit b317ac9d9f5205421ab9ae4b919f816c1c1e1ca8 diff --git a/hecl/include/HECL/HECL.hpp b/hecl/include/HECL/HECL.hpp index d6fb0b0ef..870ffe6e6 100644 --- a/hecl/include/HECL/HECL.hpp +++ b/hecl/include/HECL/HECL.hpp @@ -194,24 +194,6 @@ static inline void MakeDir(const wchar_t* dir) } #endif -static inline void MakeLink(const SystemChar* target, const SystemChar* linkPath) -{ -#if _WIN32 - HRESULT res = CreateShellLink(target, linkPath, _S("HECL Link")); /* :(( */ - if (!SUCCEEDED(res)) - { - LPWSTR messageBuffer = nullptr; - size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, res, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL); /* :((( */ - LogModule.report(LogVisor::FatalError, _S("MakeLink(%s, %s): %s"), target, linkPath, messageBuffer); - } -#else - if (symlink(target, linkPath)) /* :) */ - if (errno != EEXIST) - LogModule.report(LogVisor::FatalError, "MakeLink(%s, %s): %s", target, linkPath, strerror(errno)); -#endif -} - static inline SystemChar* Getcwd(SystemChar* buf, int maxlen) { #if HECL_UCS2 @@ -1052,7 +1034,6 @@ public: File, /**< Singular file path (confirmed with filesystem) */ Directory, /**< Singular directory path (confirmed with filesystem) */ Glob, /**< Glob-path (whenever one or more '*' occurs in syntax) */ - Link /**< Link (symlink on POSIX, ShellLink on Windows) */ }; /** @@ -1071,12 +1052,6 @@ public: */ Time getModtime() const; - /** - * @brief For link paths, get the target path - * @return Target path - */ - ProjectPath resolveLink() const; - /** * @brief Insert directory children into list * @param outPaths list to append children to @@ -1115,20 +1090,6 @@ public: */ void makeDir() const {MakeDir(m_absPath.c_str());} - /** - * @brief Create relative symbolic link at calling path targeting another path - * @param target Path to target - */ - void makeLinkTo(const ProjectPath& target) const - { - SystemString relTarget; - for (SystemChar ch : m_relPath) - if (ch == _S('/') || ch == _S('\\')) - relTarget += _S("../"); - relTarget += target.m_relPath; - MakeLink(relTarget.c_str(), m_absPath.c_str()); - } - /** * @brief Fetch project that contains path * @return Project diff --git a/hecl/include/HECL/winsupport.hpp b/hecl/include/HECL/winsupport.hpp index 1d2f3f983..137153269 100644 --- a/hecl/include/HECL/winsupport.hpp +++ b/hecl/include/HECL/winsupport.hpp @@ -10,8 +10,5 @@ #include "windows.h" void* memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen); -HRESULT CreateShellLink(LPCWSTR lpszPathObj, LPCWSTR lpszPathLink, LPCWSTR lpszDesc); -HRESULT ResolveShellLink(LPCWSTR lpszLinkFile, LPWSTR lpszPath, int iPathBufferSize); -bool TestShellLink(LPCWSTR lpszLinkFile); #endif // _HECL_WINSUPPORT_H_ diff --git a/hecl/lib/Database/Project.cpp b/hecl/lib/Database/Project.cpp index 09143fd4a..5262b18db 100644 --- a/hecl/lib/Database/Project.cpp +++ b/hecl/lib/Database/Project.cpp @@ -409,24 +409,8 @@ static void VisitDirectory(const ProjectPath& dir, /* Pass 1: child file count */ int childFileCount = 0; for (auto& child : children) - { - switch (child.second.getPathType()) - { - case ProjectPath::Type::File: - { + if (child.second.getPathType() == ProjectPath::Type::File) ++childFileCount; - break; - } - case ProjectPath::Type::Link: - { - ProjectPath target = child.second.resolveLink(); - if (target.getPathType() == ProjectPath::Type::File) - ++childFileCount; - break; - } - default: break; - } - } /* Pass 2: child files */ int progNum = 0; @@ -434,25 +418,10 @@ static void VisitDirectory(const ProjectPath& dir, progress.changeDir(dir.getLastComponent()); for (auto& child : children) { - switch (child.second.getPathType()) - { - case ProjectPath::Type::File: + if (child.second.getPathType() == ProjectPath::Type::File) { progress.changeFile(child.first.c_str(), progNum++/progDenom); VisitFile(child.second, force, fast, specInsts, progress); - break; - } - case ProjectPath::Type::Link: - { - ProjectPath target = child.second.resolveLink(); - if (target.getPathType() == ProjectPath::Type::File) - { - progress.changeFile(target.getLastComponent(), progNum++/progDenom); - VisitFile(target, force, fast, specInsts, progress); - } - break; - } - default: break; } } progress.reportDirComplete(); @@ -486,24 +455,8 @@ static void VisitGlob(const ProjectPath& path, /* Pass 1: child file count */ int childFileCount = 0; for (ProjectPath& child : children) - { - switch (child.getPathType()) - { - case ProjectPath::Type::File: - { + if (child.getPathType() == ProjectPath::Type::File) ++childFileCount; - break; - } - case ProjectPath::Type::Link: - { - ProjectPath target = path.resolveLink(); - if (target.getPathType() == ProjectPath::Type::File) - ++childFileCount; - break; - } - default: break; - } - } /* Pass 2: child files */ int progNum = 0; @@ -511,45 +464,19 @@ static void VisitGlob(const ProjectPath& path, progress.changeDir(path.getLastComponent()); for (ProjectPath& child : children) { - switch (child.getPathType()) - { - case ProjectPath::Type::File: + if (child.getPathType() == ProjectPath::Type::File) { progress.changeFile(child.getLastComponent(), progNum++/progDenom); VisitFile(child, force, fast, specInsts, progress); - break; - } - case ProjectPath::Type::Link: - { - ProjectPath target = path.resolveLink(); - if (target.getPathType() == ProjectPath::Type::File) - { - progress.changeFile(target.getLastComponent(), progNum++/progDenom); - VisitFile(target, force, fast, specInsts, progress); - } - break; - } - default: break; } } progress.reportDirComplete(); /* Pass 3: child directories */ if (recursive) - { for (ProjectPath& child : children) - { - switch (child.getPathType()) - { - case ProjectPath::Type::Directory: - { + if (child.getPathType() == ProjectPath::Type::Directory) VisitDirectory(child, recursive, force, fast, specInsts, progress); - break; - } - default: break; - } - } - } } bool Project::cookPath(const ProjectPath& path, FProgress progress, @@ -573,16 +500,6 @@ bool Project::cookPath(const ProjectPath& path, FProgress progress, VisitFile(path, force, fast, specInsts, cookProg); break; } - case ProjectPath::Type::Link: - { - ProjectPath target = path.resolveLink(); - if (target.getPathType() == ProjectPath::Type::File) - { - cookProg.changeFile(target.getLastComponent(), 0.0); - VisitFile(target, force, fast, specInsts, cookProg); - } - break; - } case ProjectPath::Type::Directory: { VisitDirectory(path, recursive, force, fast, specInsts, cookProg); diff --git a/hecl/lib/ProjectPath.cpp b/hecl/lib/ProjectPath.cpp index 8a99e008e..8fd5c00d6 100644 --- a/hecl/lib/ProjectPath.cpp +++ b/hecl/lib/ProjectPath.cpp @@ -128,16 +128,6 @@ ProjectPath ProjectPath::getCookedPath(const Database::DataSpecEntry& spec) cons ProjectPath::Type ProjectPath::getPathType() const { -#if WIN32 - if (TestShellLink(m_absPath.c_str())) - return Type::Link; -#else - HECL::Sstat lnStat; - if (lstat(m_absPath.c_str(), &lnStat)) - return Type::None; - if (S_ISLNK(lnStat.st_mode)) - return Type::Link; -#endif if (std::regex_search(m_absPath, regGLOB)) return Type::Glob; Sstat theStat; @@ -191,22 +181,6 @@ Time ProjectPath::getModtime() const return Time(); } -ProjectPath ProjectPath::resolveLink() const -{ -#if WIN32 - wchar_t target[2048]; - if (FAILED(ResolveShellLink(m_absPath.c_str(), target, 2048))) - LogModule.report(LogVisor::FatalError, _S("unable to resolve link '%s'"), m_absPath.c_str()); -#else - char target[2048]; - ssize_t targetSz; - if ((targetSz = readlink(m_absPath.c_str(), target, 2048)) < 0) - LogModule.report(LogVisor::FatalError, _S("unable to resolve link '%s': %s"), m_absPath.c_str(), strerror(errno)); - target[targetSz] = '\0'; -#endif - return ProjectPath(getParentPath(), target); -} - static void _recursiveGlob(Database::Project& proj, std::vector& outPaths, size_t level, diff --git a/hecl/lib/winsupport.cpp b/hecl/lib/winsupport.cpp index 63fd406a4..cbdc9a3d6 100644 --- a/hecl/lib/winsupport.cpp +++ b/hecl/lib/winsupport.cpp @@ -34,169 +34,3 @@ void *memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen) return NULL; } - -/* Clearly, MS doesn't require enough headers for this */ -#include "winnls.h" -#include "shobjidl.h" -#include "objbase.h" -#include "objidl.h" -#include "shlguid.h" -#include "strsafe.h" - -#define HECL_MAX_PATH 2048 - -HRESULT CreateShellLink(LPCWSTR lpszPathObj, LPCWSTR lpszPathLink, LPCWSTR lpszDesc) -{ - std::wstring targetStr(lpszPathObj); - for (wchar_t& ch : targetStr) - if (ch == L'/') - ch = L'\\'; - std::wstring linkStr(lpszPathLink); - linkStr += L".lnk"; - for (wchar_t& ch : linkStr) - if (ch == L'/') - ch = L'\\'; - - HRESULT hres; - IShellLink* psl; - - // Get a pointer to the IShellLink interface. It is assumed that CoInitialize - // has already been called. - hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); - if (SUCCEEDED(hres)) - { - IPersistFile* ppf; - - // Set the path to the shortcut target and add the description. - WCHAR targetBuf[HECL_MAX_PATH]; - WCHAR linkBuf[HECL_MAX_PATH]; - WCHAR* linkFinalPart = nullptr; - GetFullPathNameW(linkStr.c_str(), HECL_MAX_PATH, linkBuf, &linkFinalPart); - if (linkFinalPart != linkBuf) - *(linkFinalPart-1) = L'\0'; - StringCbPrintfW(targetBuf, HECL_MAX_PATH, L"%s\\%s", linkBuf, targetStr.c_str()); - if (linkFinalPart != linkBuf) - *(linkFinalPart - 1) = L'\\'; - psl->SetPath(targetBuf); - psl->SetRelativePath(linkBuf, 0); - psl->SetDescription(lpszDesc); - - // Query IShellLink for the IPersistFile interface, used for saving the - // shortcut in persistent storage. - hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); - - if (SUCCEEDED(hres)) - { - // Save the link by calling IPersistFile::Save. - hres = ppf->Save(linkBuf, TRUE); - ppf->Release(); - } - psl->Release(); - } - return hres; -} - -HRESULT ResolveShellLink(LPCWSTR lpszLinkFile, LPWSTR lpszPath, int iPathBufferSize) -{ - HRESULT hres; - IShellLink* psl; - WCHAR szGotPath[HECL_MAX_PATH]; - WCHAR szDescription[HECL_MAX_PATH]; - WIN32_FIND_DATA wfd; - - *lpszPath = 0; // Assume failure - - hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); - if (SUCCEEDED(hres)) - { - IPersistFile* ppf; - - // Get a pointer to the IPersistFile interface. - hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); - - if (SUCCEEDED(hres)) - { - // Load the shortcut. - hres = ppf->Load(lpszLinkFile, STGM_READ); - - if (SUCCEEDED(hres)) - { - // Resolve the link. - HWND hwnd = GetConsoleWindow(); - if (!hwnd) - hwnd = GetTopWindow(nullptr); - hres = psl->Resolve(hwnd, 0); - - if (SUCCEEDED(hres)) - { - // Get the path to the link target. - hres = psl->GetPath(szGotPath, HECL_MAX_PATH, (WIN32_FIND_DATA*)&wfd, SLGP_SHORTPATH); - - if (SUCCEEDED(hres)) - { - // Get the description of the target. - hres = psl->GetDescription(szDescription, HECL_MAX_PATH); - - if (SUCCEEDED(hres)) - { - hres = StringCbCopy(lpszPath, iPathBufferSize, szGotPath); - } - } - } - } - - // Release the pointer to the IPersistFile interface. - ppf->Release(); - } - - // Release the pointer to the IShellLink interface. - psl->Release(); - } - return hres; -} - -bool TestShellLink(LPCWSTR lpszLinkFile) -{ - HRESULT hres; - IShellLink* psl; - - hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); - if (SUCCEEDED(hres)) - { - IPersistFile* ppf; - - // Get a pointer to the IPersistFile interface. - hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); - - if (SUCCEEDED(hres)) - { - // Load the shortcut. - hres = ppf->Load(lpszLinkFile, STGM_READ); - - if (SUCCEEDED(hres)) - { - // Resolve the link. - HWND hwnd = GetConsoleWindow(); - if (!hwnd) - hwnd = GetTopWindow(nullptr); - hres = psl->Resolve(hwnd, 0); - - if (SUCCEEDED(hres)) - { - ppf->Release(); - psl->Release(); - return true; - } - } - - // Release the pointer to the IPersistFile interface. - ppf->Release(); - } - - // Release the pointer to the IShellLink interface. - psl->Release(); - } - return false; -} - -