Bug 1687562 - Part 2: Detect whether Firefox is pinned to the taskbar. r=mhowell

Differential Revision: https://phabricator.services.mozilla.com/D105365
This commit is contained in:
Adam Gashlin
2021-02-17 05:10:53 +00:00
parent 61e489d6aa
commit 7a868953a5
2 changed files with 106 additions and 0 deletions

View File

@@ -882,6 +882,98 @@ nsWindowsShellService::CheckPinCurrentAppToTaskbar() {
return PinCurrentAppToTaskbarImpl(/* aCheckOnly */ true);
}
NS_IMETHODIMP
nsWindowsShellService::IsCurrentAppPinnedToTaskbar(/* out */ bool* aIsPinned) {
*aIsPinned = false;
wchar_t exePath[MAXPATHLEN] = {};
if (NS_WARN_IF(NS_FAILED(BinaryPath::GetLong(exePath)))) {
return NS_OK;
}
wchar_t folderChars[MAX_PATH] = {};
HRESULT hr = SHGetFolderPathW(nullptr, CSIDL_APPDATA, nullptr,
SHGFP_TYPE_CURRENT, folderChars);
if (NS_WARN_IF(FAILED(hr))) {
return NS_OK;
}
nsAutoString folder;
folder.Assign(folderChars);
if (NS_WARN_IF(folder.IsEmpty())) {
return NS_OK;
}
if (folder[folder.Length() - 1] != '\\') {
folder.AppendLiteral("\\");
}
folder.AppendLiteral(
"Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar");
nsAutoString pattern;
pattern.Assign(folder);
pattern.AppendLiteral("\\*.lnk");
WIN32_FIND_DATAW findData = {};
HANDLE hFindFile = FindFirstFileW(pattern.get(), &findData);
if (hFindFile == INVALID_HANDLE_VALUE) {
Unused << NS_WARN_IF(GetLastError() != ERROR_FILE_NOT_FOUND);
return NS_OK;
}
// Past this point we don't return until the end of the function,
// when FindClose() is called.
// Check all shortcuts until a match is found
do {
nsAutoString fileName;
fileName.Assign(folder);
fileName.AppendLiteral("\\");
fileName.Append(findData.cFileName);
// Create a shell link object for loading the shortcut
RefPtr<IShellLinkW> link;
HRESULT hr =
CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
IID_IShellLinkW, getter_AddRefs(link));
if (NS_WARN_IF(FAILED(hr))) {
continue;
}
// Load
RefPtr<IPersistFile> persist;
hr = link->QueryInterface(IID_IPersistFile, getter_AddRefs(persist));
if (NS_WARN_IF(FAILED(hr))) {
continue;
}
hr = persist->Load(fileName.get(), STGM_READ);
if (NS_WARN_IF(FAILED(hr))) {
continue;
}
// Note: AUMID is not checked, so a pin that does not group properly
// will still count as long as the exe matches.
// Check the exe path
static_assert(MAXPATHLEN == MAX_PATH);
wchar_t storedExePath[MAX_PATH] = {};
// With no flags GetPath gets a long path
hr = link->GetPath(storedExePath, ArrayLength(storedExePath), nullptr, 0);
if (FAILED(hr) || hr == S_FALSE) {
continue;
}
// Case insensitive path comparison
// NOTE: Because this compares the path directly, it is possible to
// have a false negative mismatch.
if (wcsnicmp(storedExePath, exePath, MAXPATHLEN) == 0) {
*aIsPinned = true;
break;
}
} while (FindNextFileW(hFindFile, &findData));
FindClose(hFindFile);
return NS_OK;
}
nsWindowsShellService::nsWindowsShellService() {}
nsWindowsShellService::~nsWindowsShellService() {}