@@ -882,6 +882,98 @@ nsWindowsShellService::CheckPinCurrentAppToTaskbar() {
882882 return PinCurrentAppToTaskbarImpl (/* aCheckOnly */ true );
883883}
884884
885+ NS_IMETHODIMP
886+ nsWindowsShellService::IsCurrentAppPinnedToTaskbar (/* out */ bool * aIsPinned) {
887+ *aIsPinned = false ;
888+
889+ wchar_t exePath[MAXPATHLEN ] = {};
890+ if (NS_WARN_IF (NS_FAILED (BinaryPath::GetLong (exePath)))) {
891+ return NS_OK ;
892+ }
893+
894+ wchar_t folderChars[MAX_PATH ] = {};
895+ HRESULT hr = SHGetFolderPathW (nullptr , CSIDL_APPDATA , nullptr ,
896+ SHGFP_TYPE_CURRENT , folderChars);
897+ if (NS_WARN_IF (FAILED (hr))) {
898+ return NS_OK ;
899+ }
900+
901+ nsAutoString folder;
902+ folder.Assign (folderChars);
903+ if (NS_WARN_IF (folder.IsEmpty ())) {
904+ return NS_OK ;
905+ }
906+ if (folder[folder.Length () - 1 ] != ' \\ ' ) {
907+ folder.AppendLiteral (" \\ " );
908+ }
909+ folder.AppendLiteral (
910+ " Microsoft\\ Internet Explorer\\ Quick Launch\\ User Pinned\\ TaskBar" );
911+ nsAutoString pattern;
912+ pattern.Assign (folder);
913+ pattern.AppendLiteral (" \\ *.lnk" );
914+
915+ WIN32_FIND_DATAW findData = {};
916+ HANDLE hFindFile = FindFirstFileW (pattern.get (), &findData);
917+ if (hFindFile == INVALID_HANDLE_VALUE ) {
918+ Unused << NS_WARN_IF (GetLastError () != ERROR_FILE_NOT_FOUND );
919+ return NS_OK ;
920+ }
921+ // Past this point we don't return until the end of the function,
922+ // when FindClose() is called.
923+
924+ // Check all shortcuts until a match is found
925+ do {
926+ nsAutoString fileName;
927+ fileName.Assign (folder);
928+ fileName.AppendLiteral (" \\ " );
929+ fileName.Append (findData.cFileName );
930+
931+ // Create a shell link object for loading the shortcut
932+ RefPtr<IShellLinkW> link;
933+ HRESULT hr =
934+ CoCreateInstance (CLSID_ShellLink, nullptr , CLSCTX_INPROC_SERVER ,
935+ IID_IShellLinkW, getter_AddRefs (link));
936+ if (NS_WARN_IF (FAILED (hr))) {
937+ continue ;
938+ }
939+
940+ // Load
941+ RefPtr<IPersistFile> persist;
942+ hr = link->QueryInterface (IID_IPersistFile, getter_AddRefs (persist));
943+ if (NS_WARN_IF (FAILED (hr))) {
944+ continue ;
945+ }
946+
947+ hr = persist->Load (fileName.get (), STGM_READ );
948+ if (NS_WARN_IF (FAILED (hr))) {
949+ continue ;
950+ }
951+
952+ // Note: AUMID is not checked, so a pin that does not group properly
953+ // will still count as long as the exe matches.
954+
955+ // Check the exe path
956+ static_assert (MAXPATHLEN == MAX_PATH );
957+ wchar_t storedExePath[MAX_PATH ] = {};
958+ // With no flags GetPath gets a long path
959+ hr = link->GetPath (storedExePath, ArrayLength (storedExePath), nullptr , 0 );
960+ if (FAILED (hr) || hr == S_FALSE ) {
961+ continue ;
962+ }
963+ // Case insensitive path comparison
964+ // NOTE: Because this compares the path directly, it is possible to
965+ // have a false negative mismatch.
966+ if (wcsnicmp (storedExePath, exePath, MAXPATHLEN ) == 0 ) {
967+ *aIsPinned = true ;
968+ break ;
969+ }
970+ } while (FindNextFileW (hFindFile, &findData));
971+
972+ FindClose (hFindFile);
973+
974+ return NS_OK ;
975+ }
976+
885977nsWindowsShellService::nsWindowsShellService () {}
886978
887979nsWindowsShellService::~nsWindowsShellService () {}
0 commit comments