@@ -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,147 @@ 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
+ #ifdef __MINGW32__
1490
+ return NS_ERROR_NOT_IMPLEMENTED;
1491
+ #else
1492
+ aShortcutPaths.Clear ();
1493
+
1494
+ // Get AppData\\Roaming folder using a known folder ID
1495
+ RefPtr<IKnownFolderManager> fManager ;
1496
+ RefPtr<IKnownFolder> roamingAppData;
1497
+ LPWSTR roamingAppDataW;
1498
+ nsString roamingAppDataNS;
1499
+ HRESULT hr =
1500
+ CoCreateInstance (CLSID_KnownFolderManager, nullptr , CLSCTX_INPROC_SERVER,
1501
+ IID_IKnownFolderManager, getter_AddRefs (fManager ));
1502
+ if (NS_WARN_IF(FAILED (hr))) {
1503
+ return NS_ERROR_ABORT;
1504
+ }
1505
+ fManager ->GetFolder (FOLDERID_RoamingAppData,
1506
+ roamingAppData.StartAssignment ());
1507
+ hr = roamingAppData->GetPath (0 , &roamingAppDataW);
1508
+ if (FAILED (hr)) {
1509
+ return NS_ERROR_FILE_NOT_FOUND;
1510
+ }
1511
+
1512
+ // Append taskbar pins folder to AppData\\Roaming
1513
+ roamingAppDataNS.Assign (roamingAppDataW);
1514
+ CoTaskMemFree (roamingAppDataW);
1515
+ nsString taskbarFolder =
1516
+ roamingAppDataNS + u" \\ Microsoft\\ Windows\\ Start Menu\\ Programs" _ns;
1517
+ nsString taskbarFolderWildcard = taskbarFolder + u" \\ *.lnk" _ns;
1518
+
1519
+ // Get known path for binary file for later comparison with shortcuts.
1520
+ // Returns lowercase file path which should be fine for Windows as all
1521
+ // directories and files are case-insensitive by default.
1522
+ RefPtr<nsIFile> binFile;
1523
+ nsString binPath;
1524
+ nsresult rv = XRE_GetBinaryPath (binFile.StartAssignment ());
1525
+ if (NS_WARN_IF(FAILED (rv))) {
1526
+ return NS_ERROR_FAILURE;
1527
+ }
1528
+ rv = binFile->GetPath (binPath);
1529
+ if (NS_WARN_IF(FAILED (rv))) {
1530
+ return NS_ERROR_FILE_UNRECOGNIZED_PATH;
1531
+ }
1532
+
1533
+ // Check for if first file exists with a shortcut extension (.lnk)
1534
+ WIN32_FIND_DATAW ffd;
1535
+ HANDLE fileHandle = INVALID_HANDLE_VALUE;
1536
+ fileHandle = FindFirstFileW (taskbarFolderWildcard.get (), &ffd);
1537
+ if (fileHandle == INVALID_HANDLE_VALUE) {
1538
+ // This means that no files were found in the folder which
1539
+ // doesn't imply an error.
1540
+ return NS_OK;
1541
+ }
1542
+
1543
+ do {
1544
+ // Extract shortcut target path from every
1545
+ // shortcut in the taskbar pins folder.
1546
+ nsString fileName (ffd.cFileName );
1547
+ RefPtr<IShellLinkW> link;
1548
+ RefPtr<IPropertyStore> pps;
1549
+ nsString target;
1550
+ target.SetLength (MAX_PATH);
1551
+ hr = CoCreateInstance (CLSID_ShellLink, nullptr , CLSCTX_INPROC_SERVER,
1552
+ IID_IShellLinkW, getter_AddRefs (link));
1553
+ if (NS_WARN_IF(FAILED (hr))) {
1554
+ continue ;
1555
+ }
1556
+ nsString filePath = taskbarFolder + u" \\ " _ns + fileName;
1557
+ if (NS_WARN_IF(FAILED (hr))) {
1558
+ continue ;
1559
+ }
1560
+
1561
+ // After loading shortcut, search through arguments to find if
1562
+ // it is a taskbar tab shortcut.
1563
+ hr = SHGetPropertyStoreFromParsingName (filePath.get (), nullptr ,
1564
+ GPS_READWRITE, IID_IPropertyStore,
1565
+ getter_AddRefs (pps));
1566
+ if (NS_WARN_IF(FAILED (hr)) || pps == nullptr ) {
1567
+ continue ;
1568
+ }
1569
+ PROPVARIANT propVar;
1570
+ PropVariantInit (&propVar);
1571
+ auto cleanupPropVariant =
1572
+ MakeScopeExit ([&] { PropVariantClear (&propVar); });
1573
+ // Get the PKEY_Link_Arguments property
1574
+ hr = pps->GetValue (PKEY_Link_Arguments, &propVar);
1575
+ if (NS_WARN_IF(FAILED (hr))) {
1576
+ continue ;
1577
+ }
1578
+ // Check if the argument matches
1579
+ if (!(propVar.vt == VT_LPWSTR && propVar.pwszVal != nullptr &&
1580
+ wcsstr (propVar.pwszVal , L" -taskbar-tab" ) != nullptr )) {
1581
+ continue ;
1582
+ }
1583
+
1584
+ hr = link->GetPath (target.get (), MAX_PATH, nullptr , 0 );
1585
+ if (NS_WARN_IF(FAILED (hr))) {
1586
+ continue ;
1587
+ }
1588
+
1589
+ // If shortcut target matches known binary file value
1590
+ // then add the path to the shortcut as a valid
1591
+ // shortcut. This has to be a substring search as
1592
+ // the user could have added unknown command line arguments
1593
+ // to the shortcut.
1594
+ if (_wcsnicmp (target.get (), binPath.get (), binPath.Length ()) == 0 ) {
1595
+ aShortcutPaths.AppendElement (filePath);
1596
+ }
1597
+ } while (FindNextFile (fileHandle, &ffd) != 0 );
1598
+ FindClose (fileHandle);
1599
+ return NS_OK;
1600
+ #endif
1601
+ }
1602
+
1470
1603
static nsresult PinCurrentAppToTaskbarWin10 (bool aCheckOnly,
1471
1604
const nsAString& aAppUserModelId,
1472
1605
nsAutoString aShortcutPath) {
0 commit comments