@@ -1418,23 +1418,15 @@ static nsresult ManageShortcutTaskbarPins(bool aCheckOnly, bool aPinType,
1418
1418
}
1419
1419
};
1420
1420
1421
- HRESULT hr = CoInitialize (nullptr );
1422
- if (FAILED (hr)) {
1423
- return NS_ERROR_FAILURE;
1424
- }
1425
- const struct ComUninitializer {
1426
- ~ComUninitializer () { CoUninitialize (); }
1427
- } kCUi ;
1428
-
1429
1421
mozilla::UniquePtr<__unaligned ITEMIDLIST, ILFreeDeleter> path (
1430
1422
ILCreateFromPathW (nsString (aShortcutPath).get ()));
1431
1423
if (NS_WARN_IF(!path)) {
1432
1424
return NS_ERROR_FILE_NOT_FOUND;
1433
1425
}
1434
1426
1435
1427
IPinnedList3* pinnedList = nullptr ;
1436
- hr = CoCreateInstance (CLSID_TaskbandPin, NULL , CLSCTX_INPROC_SERVER,
1437
- IID_IPinnedList3, (void **)&pinnedList);
1428
+ HRESULT hr = CoCreateInstance (CLSID_TaskbandPin, NULL , CLSCTX_INPROC_SERVER,
1429
+ IID_IPinnedList3, (void **)&pinnedList);
1438
1430
if (FAILED (hr) || !pinnedList) {
1439
1431
return NS_ERROR_NOT_AVAILABLE;
1440
1432
}
@@ -1467,6 +1459,144 @@ nsWindowsShellService::UnpinShortcutFromTaskbar(
1467
1459
return ManageShortcutTaskbarPins (runInTestMode, pinType, aShortcutPath);
1468
1460
}
1469
1461
1462
+ NS_IMETHODIMP
1463
+ nsWindowsShellService::GetTaskbarTabShortcutPath (const nsAString& aShortcutName,
1464
+ nsAString& aRetPath) {
1465
+ // The taskbar tab shortcut will always be in
1466
+ // %APPDATA%\Microsoft\Windows\Start Menu\Programs
1467
+ RefPtr<IKnownFolderManager> fManager ;
1468
+ RefPtr<IKnownFolder> progFolder;
1469
+ LPWSTR progFolderW;
1470
+ nsString progFolderNS;
1471
+ HRESULT hr =
1472
+ CoCreateInstance (CLSID_KnownFolderManager, nullptr , CLSCTX_INPROC_SERVER,
1473
+ IID_IKnownFolderManager, getter_AddRefs (fManager ));
1474
+ if (NS_WARN_IF(FAILED (hr))) {
1475
+ return NS_ERROR_ABORT;
1476
+ }
1477
+ fManager ->GetFolder (FOLDERID_Programs, progFolder.StartAssignment ());
1478
+ hr = progFolder->GetPath (0 , &progFolderW);
1479
+ if (FAILED (hr)) {
1480
+ return NS_ERROR_FILE_NOT_FOUND;
1481
+ }
1482
+ progFolderNS.Assign (progFolderW);
1483
+ aRetPath = progFolderNS + u" \\ " _ns + aShortcutName + u" .lnk" _ns;
1484
+ return NS_OK;
1485
+ }
1486
+
1487
+ NS_IMETHODIMP
1488
+ nsWindowsShellService::GetTaskbarTabPins (nsTArray<nsString>& aShortcutPaths) {
1489
+ aShortcutPaths.Clear ();
1490
+
1491
+ // Get AppData\\Roaming folder using a known folder ID
1492
+ RefPtr<IKnownFolderManager> fManager ;
1493
+ RefPtr<IKnownFolder> roamingAppData;
1494
+ LPWSTR roamingAppDataW;
1495
+ nsString roamingAppDataNS;
1496
+ HRESULT hr =
1497
+ CoCreateInstance (CLSID_KnownFolderManager, nullptr , CLSCTX_INPROC_SERVER,
1498
+ IID_IKnownFolderManager, getter_AddRefs (fManager ));
1499
+ if (NS_WARN_IF(FAILED (hr))) {
1500
+ return NS_ERROR_ABORT;
1501
+ }
1502
+ fManager ->GetFolder (FOLDERID_RoamingAppData,
1503
+ roamingAppData.StartAssignment ());
1504
+ hr = roamingAppData->GetPath (0 , &roamingAppDataW);
1505
+ if (FAILED (hr)) {
1506
+ return NS_ERROR_FILE_NOT_FOUND;
1507
+ }
1508
+
1509
+ // Append taskbar pins folder to AppData\\Roaming
1510
+ roamingAppDataNS.Assign (roamingAppDataW);
1511
+ CoTaskMemFree (roamingAppDataW);
1512
+ nsString taskbarFolder =
1513
+ roamingAppDataNS + u" \\ Microsoft\\ Windows\\ Start Menu\\ Programs" _ns;
1514
+ nsString taskbarFolderWildcard = taskbarFolder + u" \\ *.lnk" _ns;
1515
+
1516
+ // Get known path for binary file for later comparison with shortcuts.
1517
+ // Returns lowercase file path which should be fine for Windows as all
1518
+ // directories and files are case-insensitive by default.
1519
+ RefPtr<nsIFile> binFile;
1520
+ nsString binPath;
1521
+ nsresult rv = XRE_GetBinaryPath (binFile.StartAssignment ());
1522
+ if (NS_WARN_IF(FAILED (rv))) {
1523
+ return NS_ERROR_FAILURE;
1524
+ }
1525
+ rv = binFile->GetPath (binPath);
1526
+ if (NS_WARN_IF(FAILED (rv))) {
1527
+ return NS_ERROR_FILE_UNRECOGNIZED_PATH;
1528
+ }
1529
+
1530
+ // Check for if first file exists with a shortcut extension (.lnk)
1531
+ WIN32_FIND_DATAW ffd;
1532
+ HANDLE fileHandle = INVALID_HANDLE_VALUE;
1533
+ fileHandle = FindFirstFileW (taskbarFolderWildcard.get (), &ffd);
1534
+ if (fileHandle == INVALID_HANDLE_VALUE) {
1535
+ // This means that no files were found in the folder which
1536
+ // doesn't imply an error.
1537
+ return NS_OK;
1538
+ }
1539
+
1540
+ do {
1541
+ // Extract shortcut target path from every
1542
+ // shortcut in the taskbar pins folder.
1543
+ nsString fileName (ffd.cFileName );
1544
+ RefPtr<IShellLinkW> link ;
1545
+ RefPtr<IPersistFile> ppf;
1546
+ RefPtr<IPropertyStore> pps;
1547
+ nsString target;
1548
+ target.SetLength (MAX_PATH);
1549
+ hr = CoCreateInstance (CLSID_ShellLink, nullptr , CLSCTX_INPROC_SERVER,
1550
+ IID_IShellLinkW, getter_AddRefs (link ));
1551
+ if (NS_WARN_IF(FAILED (hr))) {
1552
+ continue ;
1553
+ }
1554
+ nsString filePath = taskbarFolder + u" \\ " _ns + fileName;
1555
+ if (NS_WARN_IF(FAILED (hr))) {
1556
+ continue ;
1557
+ }
1558
+
1559
+ // After loading shortcut, search through arguments to find if
1560
+ // it is a taskbar tab shortcut.
1561
+ hr = SHGetPropertyStoreFromParsingName (filePath.get (), nullptr ,
1562
+ GPS_READWRITE, IID_IPropertyStore,
1563
+ getter_AddRefs (pps));
1564
+ if (NS_WARN_IF(FAILED (hr)) || pps == nullptr ) {
1565
+ continue ;
1566
+ }
1567
+ PROPVARIANT propVar;
1568
+ PropVariantInit (&propVar);
1569
+ auto cleanupPropVariant =
1570
+ MakeScopeExit ([&] { PropVariantClear (&propVar); });
1571
+ // Get the PKEY_Link_Arguments property
1572
+ hr = pps->GetValue (PKEY_Link_Arguments, &propVar);
1573
+ if (NS_WARN_IF(FAILED (hr))) {
1574
+ continue ;
1575
+ }
1576
+ // Check if the argument matches
1577
+ if (!(propVar.vt == VT_LPWSTR && propVar.pwszVal != nullptr &&
1578
+ wcsstr (propVar.pwszVal , L" -taskbar-tab" ) != nullptr )) {
1579
+ continue ;
1580
+ }
1581
+
1582
+ hr = link ->GetPath (target.get (), MAX_PATH, nullptr , 0 );
1583
+ if (NS_WARN_IF(FAILED (hr))) {
1584
+ continue ;
1585
+ }
1586
+
1587
+ // If shortcut target matches known binary file value
1588
+ // then add the path to the shortcut as a valid
1589
+ // shortcut. This has to be a substring search as
1590
+ // the user could have added unknown command line arguments
1591
+ // to the shortcut.
1592
+ if (_wcsnicmp (target.get (), binPath.get (), binPath.Length ()) == 0 ) {
1593
+ aShortcutPaths.AppendElement (filePath);
1594
+ }
1595
+ } while (FindNextFile (fileHandle, &ffd) != 0 );
1596
+ FindClose (fileHandle);
1597
+ return NS_OK;
1598
+ }
1599
+
1470
1600
static nsresult PinCurrentAppToTaskbarWin10 (bool aCheckOnly,
1471
1601
const nsAString& aAppUserModelId,
1472
1602
nsAutoString aShortcutPath) {
0 commit comments