/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.idl" interface nsIFile; [scriptable, uuid(fb9b59db-5a91-4e67-92b6-35e7d6e6d3fd)] interface nsIWindowsShellService : nsISupports { /* * Creates a new shortcut (.lnk) file. This shortcut will be recorded in * a new shortcuts log file located in %PROGRAMDATA%\Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38 * that is named after the currently running application and current user, eg: * Firefox_user123_shortcuts.ini. * * For reasons that we haven't been able to pin down, these shortcuts get created with * extra metadata on them (KnownFolderDataBlock, SpecialFolderDataBlock) that cause * the Windows ShellLink classes to improperly read their target path with certain * parameters. This causes any 32-bit programs that read the links (such as our * installer and uninstaller) to think that 64-bit installs are located in the 32-bit * Program Files directory. * See https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/6f2e7920-50a9-459d-bfdd-316e459e87c0/ishelllink-getpath-returns-wrong-folder-for-64-bit-application-when-called-from-32-bit-application * for some additional discussion of this. * * @param aBinary Target file of the shortcut. * @param aArguments Arguments to set for the shortcut. May be empty. * @param aDescription The description of the shortcut. The string used here * shows up as the hover text of the shortcut in Explorer and on the * Taskbar (if the shortcut is pinned there). * @param aIconFile The file containing the desired icon for the shortcut. This * can be the same file as aBinary. * @param aIconIndex The index of the in aIconFile. Note that this is 0 based index * that IShellLinkW requires, _not_ a Resource ID that is sometimes used * for icons. * @param aAppUserModelId The App User Model ID to set for the shortcut. This will * affect which icon on the Taskbar the application groups with when first * launched. * @param aShortcutFolder The special Windows folder to create the shortcut in. One of: * CommonStartMenu, StartMenu, PublicDesktop, Desktop, or QuickLaunch. * @param aShortcutName The filename of the shortcut within aShortcutFolder. * @return The full native path to the created shortcut. * * @throws NS_ERROR_INVALID_ARG if an invalid shortcut folder is passed * @throws NS_ERROR_FILE_NOT_FOUND if the shortcut file or shortcuts log cannot be * created or accessed * @throws NS_ERROR_FAILURE for other types of failures */ [implicit_jscontext] Promise createShortcut(in nsIFile aBinary, in Array aArguments, in AString aDescription, in nsIFile aIconFile, in unsigned short aIconIndex, in AString aAppUserModelId, in AString aShortcutFolder, in AString aShortcutName); /* * Searches the %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup * folder and returns an array with the path of all shortcuts with a target matching the * current Firefox install location. The AUMID isn't required here as we are only looking * for the currently running binary, whether that's firefox.exe or the private browsing * proxy executable. * * It is possible to return an empty array if no shortcuts are found. * * @return An array of paths for all launch on login shortcuts.s * * @throws NS_ERROR_ABORT * if instance cannot be created. * @throws NS_ERROR_FILE_NOT_FOUND * if %USERPROFILE%\AppData\Roaming\ cannot be opened. * @throws NS_ERROR_FAILURE * if the executable file cannot be found. * @throws NS_ERROR_FILE_UNRECOGNIZED_PATH * if the executable file cannot be converted into a string. */ Array getLaunchOnLoginShortcuts(); /* * Pin the current app to the taskbar. If aPrivateBrowsing is true, the * Private Browsing version of the app (with a different icon and launch * arguments) will be pinned instead. * * This MUST only be used in response to an active request from the user. * * If it exists, uses an existing shortcut on the Desktop or Start Menu, * which would have been created by the installer (for All Users or * Current User). If none can be found, one will be created with the correct * AUMID for proper launching and grouping. * * NOTE: It is possible for the shortcut match to fail even when a * shortcut refers to the current executable, if the paths differ due * to e.g. symlinks. This should be rare. * * This will definitely fail on an OS before Windows 10 build 1809 * (October 2018 Update). * * NOTE: Can only run on the main thread, but the actual work occurs on a * background thread. * * @throws NS_ERROR_NOT_SAME_THREAD * if called off main thread. * @throws NS_ERROR_NOT_AVAILABLE * if OS is not at least Windows 10 build 1809, or if creating the * Taskband Pin object fails * @throws NS_ERROR_FAILURE * for unexpected errors * * @rejects NS_ERROR_FILE_NOT_FOUND * if a shortcut matching this app's AUMID and exe path wasn't found * * @returns {Promise} A promise that resolves to |undefined| if * successful or rejects with an nserror. */ [implicit_jscontext] Promise pinCurrentAppToTaskbarAsync(in boolean aPrivateBrowsing); /* * Do a dry run of pinCurrentAppToTaskbar(). * * NOTE: Can only be run on the main thread, but the actual work occurs on a * background thread. * * This does all the same checks and setup, throws the same errors, but doesn't * do the final step of creating the pin. * * @throws same as pinCurrentAppToTaskbarAsync() * @rejects same as pinCurrentAppToTaskbarAsync() * @returns same as pinCurrentAppToTaskbarAsync() */ [implicit_jscontext] Promise checkPinCurrentAppToTaskbarAsync(in boolean aPrivateBrowsing); /* * Search for the current executable among taskbar pins * * NOTE: Can only be run on the main thread, but the actual work occurs on a * background thread. * * NOTE: It is possible for the check to fail even when a taskbar pin refers * to this executable, if the paths differ due to e.g. symlinks. * It is also possible for the check to succeed with a shortcut that doesn't * actually appear on the taskbar. * These cases should be rare. * * @return Promise that always resolves, true if pinned, false otherwise * @throws NS_ERROR_NOT_SAME_THREAD if not run on the main thread * */ [implicit_jscontext] Promise isCurrentAppPinnedToTaskbarAsync(in AString aumid); /* * Similar to createShortcut except it removes most of the checking in that * function that ensures we are pinning a Firefox executable instead allowing * any shortcut to be pinned. * * This function should not be called unless it is certain that it's * necessary given how few checks there are within. * @param aShortcutPath * A path to the .lnk file that should be pinned to the taskbar. * @throws NS_ERROR_FAILURE * If the COM service could not be initialized * @throws NS_ERROR_FILE_NOT_FOUND * If aShortcutPath cannot be found * @throws NS_ERROR_NOT_AVAILABLE * If the taskbar pinning service cannot be initialized * @throws NS_ERROR_FILE_ACCESS_DENIED * If the taskbar pins cannot be modified */ void pinShortcutToTaskbar(in AString aShortcutPath); /* * This function is a counterpart to pinShortcutToTaskbar and allows * the unpinning of any shortcut, including non-Firefox executables, * without the checks of createShortcut. * * This function should not be called unless it is certain that it's * necessary given how few checks there are within. * @param aShortcutPath * A path to the .lnk file that should be pinned to the taskbar. * @throws NS_ERROR_FAILURE * If the COM service could not be initialized * @throws NS_ERROR_FILE_NOT_FOUND * If aShortcutPath cannot be found * @throws NS_ERROR_NOT_AVAILABLE * If the taskbar pinning service cannot be initialized * @throws NS_ERROR_FILE_ACCESS_DENIED * If the taskbar pins cannot be modified */ void unpinShortcutFromTaskbar(in AString aShortcutPath); /** * Gets the full path of a taskbar tab shortcut. * * @param aShortcutName * The name of the taskbar tab shortcut, excluding the file extension. * @throws NS_ERROR_FAILURE * If the user token cannot be found. * @throws NS_ERROR_ABORT * If converting the sid to a string fails. * * @return The full path of the taskbar tab shortcut */ AString getTaskbarTabShortcutPath(in AString aShortcutName); /* * Searches the %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start * Menu\Programs folder and returns an array with the path of all * shortcuts with a target matching the current Firefox install location * and the -taskbar-tab argument. * * It is possible to return an empty array if no shortcuts are found. * * @return An array of paths for all taskbar tab shortcuts. * * @throws NS_ERROR_NOT_IMPLEMENTED * if run on a MinGW compilation * @throws NS_ERROR_ABORT * if instance cannot be created. * @throws NS_ERROR_FILE_NOT_FOUND * if %USERPROFILE%\AppData\Roaming\ cannot be opened. * @throws NS_ERROR_FAILURE * if the executable file cannot be found. * @throws NS_ERROR_FILE_UNRECOGNIZED_PATH * if the executable file cannot be converted into a string. */ Array getTaskbarTabPins(); /* * Determine where a given shortcut likely appears in the shell. * * Returns one of: * - "StartMenu" or "StartMenuPrivate", Current User or All Users Start * Menu, including pins * - "Desktop" or "DesktopPrivate", Current User or All Users Desktop * - "Taskbar" or "TaskbarPrivate", Taskbar Pins * - "" otherwise * * If a Private Browsing shortcut was used to launch, the "Private" * variant of one of the above entries will be returned. * * NOTE: This tries to avoid I/O, so paths are compared directly as * strings, which may not be accurate in all cases. It is intended * for noncritical telemetry use. */ AString classifyShortcut(in AString aPath); [implicit_jscontext] Promise hasMatchingShortcut(in AString aAUMID, in boolean aPrivateBrowsing); /* * Check if setDefaultBrowserUserChoice() is expected to succeed. * * This checks the ProgIDs for this installation, and the hash of the existing * UserChoice association. * * @return true if the check succeeds, false otherwise. */ boolean canSetDefaultBrowserUserChoice(); /* * checkAllProgIDsExist() and checkBrowserUserChoiceHashes() are components * of canSetDefaultBrowserUserChoice(), broken out for telemetry purposes. * * @return true if the check succeeds, false otherwise. */ boolean checkAllProgIDsExist(); boolean checkBrowserUserChoiceHashes(); /* * Determines whether or not Firefox is the "Default Handler", i.e., * is registered to handle, the given file extension (like ".pdf") * or protocol (like "https"). */ boolean isDefaultHandlerFor(in AString aFileExtensionOrProtocol); /* * Return the Windows ProgID currently registered to handle the gven * file extension (like ".pdf") or protocol (like "https"). * * @return string ProgID, or "" when no association is registered. * @throws NS_ERROR_FAILURE when the file extension or protocol * cannot be determined. */ AString queryCurrentDefaultHandlerFor(in AString aFileExtensionOrProtocol); };