diff --git a/src/wintoastlib.cpp b/src/wintoastlib.cpp index 0895ff7..ac8d5cf 100644 --- a/src/wintoastlib.cpp +++ b/src/wintoastlib.cpp @@ -213,8 +213,8 @@ namespace Util { } - inline HRESULT defaultShellLinksDirectory(_In_ WCHAR* path, _In_ DWORD nSize = MAX_PATH) { - DWORD written = GetEnvironmentVariableW(L"APPDATA", path, nSize); + inline HRESULT commonShellLinksDirectory(_In_ const WCHAR* baseEnv, _In_ WCHAR* path, _In_ DWORD nSize) { + DWORD written = GetEnvironmentVariableW(baseEnv, path, nSize); HRESULT hr = written > 0 ? S_OK : E_INVALIDARG; if (SUCCEEDED(hr)) { errno_t result = wcscat_s(path, nSize, DEFAULT_SHELL_LINKS_PATH); @@ -224,8 +224,8 @@ namespace Util { return hr; } - inline HRESULT defaultShellLinkPath(const std::wstring& appname, _In_ WCHAR* path, _In_ DWORD nSize = MAX_PATH) { - HRESULT hr = defaultShellLinksDirectory(path, nSize); + inline HRESULT commonShellLinkPath(_In_ const WCHAR* baseEnv, const std::wstring& appname, _In_ WCHAR* path, _In_ DWORD nSize) { + HRESULT hr = commonShellLinksDirectory(baseEnv, path, nSize); if (SUCCEEDED(hr)) { const std::wstring appLink(appname + DEFAULT_LINK_FORMAT); errno_t result = wcscat_s(path, nSize, appLink.c_str()); @@ -235,6 +235,13 @@ namespace Util { return hr; } + inline HRESULT defaultUserShellLinkPath(const std::wstring& appname, _In_ WCHAR* path, _In_ DWORD nSize = MAX_PATH) { + return commonShellLinkPath(L"APPDATA", appname, path, nSize); + } + + inline HRESULT defaultSystemShellLinkPath(const std::wstring& appname, _In_ WCHAR* path, _In_ DWORD nSize = MAX_PATH) { + return commonShellLinkPath(L"PROGRAMDATA", appname, path, nSize); + } inline PCWSTR AsString(ComPtr &xmlDocument) { HSTRING xml; @@ -523,12 +530,19 @@ const std::wstring& WinToast::appUserModelId() const { HRESULT WinToast::validateShellLinkHelper(_Out_ bool& wasChanged) { WCHAR path[MAX_PATH] = { L'\0' }; - Util::defaultShellLinkPath(_appName, path); + Util::defaultUserShellLinkPath(_appName, path); // Check if the file exist DWORD attr = GetFileAttributesW(path); if (attr >= 0xFFFFFFF) { - DEBUG_MSG("Error, shell link not found. Try to create a new one in: " << path); - return E_FAIL; + // The shortcut may be in the system Start Menu. + WCHAR systemPath[MAX_PATH] = { L'\0' }; + Util::defaultSystemShellLinkPath(_appName, systemPath); + attr = GetFileAttributesW(systemPath); + if (attr >= 0xFFFFFFF) { + DEBUG_MSG("Error, shell link not found. Try to create a new one in: " << path); + return E_FAIL; + } + wcscpy(path, systemPath); } // Let's load the file as shell link to validate. @@ -543,7 +557,7 @@ HRESULT WinToast::validateShellLinkHelper(_Out_ bool& wasChanged) { ComPtr persistFile; hr = shellLink.As(&persistFile); if (SUCCEEDED(hr)) { - hr = persistFile->Load(path, STGM_READWRITE); + hr = persistFile->Load(path, STGM_READ); if (SUCCEEDED(hr)) { ComPtr propertyStore; hr = shellLink.As(&propertyStore); @@ -583,7 +597,7 @@ HRESULT WinToast::validateShellLinkHelper(_Out_ bool& wasChanged) { HRESULT WinToast::createShellLinkHelper() { WCHAR exePath[MAX_PATH]{L'\0'}; WCHAR slPath[MAX_PATH]{L'\0'}; - Util::defaultShellLinkPath(_appName, slPath); + Util::defaultUserShellLinkPath(_appName, slPath); Util::defaultExecutablePath(exePath); ComPtr shellLink; HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink));