LinkResolver.cpp 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /*
  2. * LinkResolver.cpp
  3. * ----------------
  4. * Purpose: Resolve Windows shell link targets
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #include "stdafx.h"
  10. #include "LinkResolver.h"
  11. #include <atlconv.h>
  12. OPENMPT_NAMESPACE_BEGIN
  13. LinkResolver::LinkResolver()
  14. {
  15. HRESULT result = CoCreateInstance(CLSID_ShellLink,
  16. 0,
  17. CLSCTX_INPROC_SERVER,
  18. IID_IShellLink,
  19. reinterpret_cast<LPVOID *>(&psl));
  20. if(SUCCEEDED(result) && psl != nullptr)
  21. {
  22. psl->QueryInterface(IID_IPersistFile, reinterpret_cast<LPVOID *>(&ppf));
  23. }
  24. }
  25. LinkResolver::~LinkResolver()
  26. {
  27. if(ppf != nullptr)
  28. ppf->Release();
  29. if(psl != nullptr)
  30. psl->Release();
  31. }
  32. mpt::PathString LinkResolver::Resolve(const TCHAR *inPath)
  33. {
  34. if(ppf == nullptr)
  35. return {};
  36. SHFILEINFO info;
  37. Clear(info);
  38. if((SHGetFileInfo(inPath, 0, &info, sizeof(info), SHGFI_ATTRIBUTES) == 0) || !(info.dwAttributes & SFGAO_LINK))
  39. return {};
  40. USES_CONVERSION; // T2COLE needs this
  41. if(ppf != nullptr && SUCCEEDED(ppf->Load(T2COLE(inPath), STGM_READ)))
  42. {
  43. if(SUCCEEDED(psl->Resolve(AfxGetMainWnd()->m_hWnd, MAKELONG(SLR_ANY_MATCH | SLR_NO_UI | SLR_NOSEARCH, 100))))
  44. {
  45. TCHAR outPath[MAX_PATH];
  46. psl->GetPath(outPath, mpt::saturate_cast<int>(std::size(outPath)), nullptr, 0);
  47. return mpt::PathString::FromNative(outPath);
  48. }
  49. }
  50. return {};
  51. }
  52. OPENMPT_NAMESPACE_END