tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsIWindowsShellService.idl (16877B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "imgIContainer.idl"
      6 #include "nsIShellService.idl"
      7 
      8 interface nsIFile;
      9 
     10 [scriptable, uuid(fb9b59db-5a91-4e67-92b6-35e7d6e6d3fd)]
     11 interface nsIWindowsShellService : nsIShellService
     12 {
     13  /*
     14   * Creates a new shortcut (.lnk) file. This shortcut will be recorded in
     15   * a new shortcuts log file located in %PROGRAMDATA%\Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38
     16   * that is named after the currently running application and current user, eg:
     17   * Firefox_user123_shortcuts.ini.
     18   *
     19   * For reasons that we haven't been able to pin down, these shortcuts get created with
     20   * extra metadata on them (KnownFolderDataBlock, SpecialFolderDataBlock) that cause
     21   * the Windows ShellLink classes to improperly read their target path with certain
     22   * parameters. This causes any 32-bit programs that read the links (such as our
     23   * installer and uninstaller) to think that 64-bit installs are located in the 32-bit
     24   * Program Files directory.
     25   * 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
     26   * for some additional discussion of this.
     27   *
     28   * @param aBinary Target file of the shortcut.
     29   * @param aArguments Arguments to set for the shortcut. May be empty.
     30   * @param aDescription The description of the shortcut. The string used here
     31   *        shows up as the hover text of the shortcut in Explorer and on the
     32   *        Taskbar (if the shortcut is pinned there).
     33   * @param aIconFile The file containing the desired icon for the shortcut. This
     34   *        can be the same file as aBinary.
     35   * @param aIconIndex The index of the in aIconFile. Note that this is 0 based index
     36   *        that IShellLinkW requires, _not_ a Resource ID that is sometimes used
     37   *        for icons.
     38   * @param aAppUserModelId The App User Model ID to set for the shortcut. This will
     39   *        affect which icon on the Taskbar the application groups with when first
     40   *        launched.
     41   * @param aShortcutFolder The special Windows folder to create the shortcut in. Must be
     42   *        either "Programs" or "Desktop".
     43   * @param aShortcutRelativePath The relative path of the shortcut from the shortcut
     44   *        folder.
     45   * @return The full native path to the created shortcut.
     46   *
     47   * @throws NS_ERROR_INVALID_ARG if an invalid shortcut folder is passed
     48   * @throws NS_ERROR_FILE_NOT_FOUND if the shortcut file or shortcuts log cannot be
     49   *         created or accessed
     50   * @throws NS_ERROR_FAILURE for other types of failures
     51   */
     52  [implicit_jscontext]
     53  Promise createShortcut(in nsIFile aBinary, in Array<AString> aArguments,
     54    in AString aDescription, in nsIFile aIconFile, in unsigned short aIconIndex,
     55    in AString aAppUserModelId, in AString aShortcutFolder,
     56    in AString aShortcutRelativePath);
     57 
     58  /*
     59   * Deletes the provided shortcut path relative to the shortcut folder, and removes it
     60   * from the uninstaller's log file.
     61   *
     62   * @param aShortcutFolder The special Windows folder to create the shortcut in.
     63   *        Should be either Desktop or StartMenu.
     64   * @param aShortcutRelativePath The relative path to the shortcut file from the folder.
     65   *
     66   * @throws NS_ERROR_INVALID_ARG if an invalid shortcut folder is passed
     67   */
     68  [implicit_jscontext]
     69  Promise deleteShortcut(in AString aShortcutFolder, in AString aShortcutRelativePath);
     70 
     71  /*
     72   * Searches the %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
     73   * folder and returns an array with the path of all shortcuts with a target matching the
     74   * current Firefox install location. The AUMID isn't required here as we are only looking
     75   * for the currently running binary, whether that's firefox.exe or the private browsing
     76   * proxy executable.
     77   *
     78   * It is possible to return an empty array if no shortcuts are found.
     79   *
     80   * @return An array of paths for all launch on login shortcuts.s
     81   *
     82   * @throws NS_ERROR_ABORT
     83   *         if instance cannot be created.
     84   * @throws NS_ERROR_FILE_NOT_FOUND
     85   *         if %USERPROFILE%\AppData\Roaming\ cannot be opened.
     86   * @throws NS_ERROR_FAILURE
     87   *         if the executable file cannot be found.
     88   * @throws NS_ERROR_FILE_UNRECOGNIZED_PATH
     89   *         if the executable file cannot be converted into a string.
     90   */
     91 
     92  Array<AString> getLaunchOnLoginShortcuts();
     93 
     94  /*
     95   * Pins the current application to the Windows Start Menu
     96   *
     97   * The APIs used within this function are MSIX only and
     98   * will also not work on MINGW.
     99   *
    100   * @param aCheckOnly If only testing whether pinning is possible
    101   *
    102   * @return True if the application was successfully pinned
    103   *              to the Start Menu.
    104   *
    105   * @throws NS_ERROR_NOT_AVAILABLE
    106   *         If used on a non-MSIX build
    107   * @throws NS_ERROR_NOT_IMPLEMENTED
    108   *         If used on a MinGW build
    109   * @throws NS_ERROR_NOT_SAME_THREAD
    110   *         If called off main thread
    111   * @throws NS_ERROR_FAILURE
    112   *         For Windows API failures
    113   */
    114  [implicit_jscontext]
    115  Promise pinCurrentAppToStartMenuAsync(in boolean aCheckOnly);
    116 
    117  /*
    118   * Whether the current app is among Windows Start Menu pins
    119   *
    120   * @return True if pinned, false otherwise
    121   *
    122   * The APIs used within this function are MSIX only and
    123   * will also not work on MINGW.
    124   *
    125   * @throws NS_ERROR_NOT_AVAILABLE
    126   *         If used on a non-MSIX build
    127   * @throws NS_ERROR_NOT_IMPLEMENTED
    128   *         If used on a MinGW build
    129   * @throws NS_ERROR_NOT_SAME_THREAD
    130   *         If called off main thread
    131   * @throws NS_ERROR_FAILURE
    132   *         For Windows API failures
    133   */
    134  [implicit_jscontext]
    135  Promise isCurrentAppPinnedToStartMenuAsync();
    136 
    137  /*
    138   * Disables the startup task corresponding to the provided taskId
    139   * to launch upon OS login. The startup task is declared
    140   * within the App Manifest.
    141   *
    142   * If the task was previously disabled by the user this function
    143   * will not re-enable it.
    144   *
    145   * The APIs used within this function are MSIX only and
    146   * will also not work on MINGW.
    147   *
    148   * @param aTaskId Target taskId to enable
    149   *
    150   * @return True if the application was successfully set up to
    151   *         launch on OS login.
    152   *
    153   * @throws NS_ERROR_NOT_AVAILABLE
    154   *         If used on a non-MSIX build
    155   * @throws NS_ERROR_NOT_IMPLEMENTED
    156   *         If used on a MinGW build
    157   * @throws NS_ERROR_NOT_SAME_THREAD
    158   *         If called off main thread
    159   * @throws NS_ERROR_FAILURE
    160   *         For other types of failures
    161   */
    162  [implicit_jscontext]
    163  Promise enableLaunchOnLoginMSIXAsync(in AString aTaskId);
    164 
    165  /*
    166   * Disables the startup task corresponding to the provided taskId
    167   * to launch upon OS login. The startup task is declared
    168   * within the App Manifest.
    169   *
    170   * The APIs used within this function are MSIX only and
    171   * will also not work on MINGW.
    172   *
    173   * @param aTaskId Target taskId to disable
    174   *
    175   * @return True if the application was successfully disabled from
    176   *         launching on OS login.
    177   *
    178   * @throws NS_ERROR_NOT_AVAILABLE
    179   *         If used on a non-MSIX build
    180   * @throws NS_ERROR_NOT_IMPLEMENTED
    181   *         If used on a MinGW build
    182   * @throws NS_ERROR_NOT_SAME_THREAD
    183   *         If called off main thread
    184   * @throws NS_ERROR_FAILURE
    185   *         For other types of failures
    186   */
    187  [implicit_jscontext]
    188  Promise disableLaunchOnLoginMSIXAsync(in AString aTaskId);
    189 
    190  /*
    191   * Determines if the startup task corresponding to the provided taskId to
    192   * launch upon OS login is enabled. The startup task is declared
    193   * within the App Manifest. The APIs used within this function are MSIX
    194   * only and will also not work on MINGW.
    195   *
    196   * If the user has disabled the application from launching on login, it
    197   * cannot be re-enabled by the application.
    198   *
    199   * @param aTaskId Target taskId to check status of
    200   *
    201   * @return 0/1/2/3 if the application's OS launch on login is
    202             disabled in settings / disabled / enabled / enabled by policy
    203   *
    204   * @throws NS_ERROR_NOT_AVAILABLE
    205   *         If used on a non-MSIX build
    206   * @throws NS_ERROR_NOT_IMPLEMENTED
    207   *         If used on a MinGW build
    208   * @throws NS_ERROR_NOT_SAME_THREAD
    209   *         If called off main thread
    210   * @throws NS_ERROR_FAILURE
    211   *         For other types of failures
    212   */
    213 
    214  cenum LaunchOnLoginEnabledEnumerator : 8 {
    215    LAUNCH_ON_LOGIN_DISABLED_BY_SETTINGS = 0,
    216    LAUNCH_ON_LOGIN_DISABLED = 1,
    217    LAUNCH_ON_LOGIN_ENABLED = 2,
    218    LAUNCH_ON_LOGIN_ENABLED_BY_POLICY = 3,
    219  };
    220 
    221  [implicit_jscontext]
    222  Promise getLaunchOnLoginEnabledMSIXAsync(in AString aTaskId);
    223 
    224  /*
    225   * Pin the current app to the taskbar. If aPrivateBrowsing is true, the
    226   * Private Browsing version of the app (with a different icon and launch
    227   * arguments) will be pinned instead.
    228   *
    229   * This MUST only be used in response to an active request from the user.
    230   *
    231   * If it exists, uses an existing shortcut on the Desktop or Start Menu,
    232   * which would have been created by the installer (for All Users or
    233   * Current User). If none can be found, one will be created with the correct
    234   * AUMID for proper launching and grouping.
    235   *
    236   * NOTE: It is possible for the shortcut match to fail even when a
    237   * shortcut refers to the current executable, if the paths differ due
    238   * to e.g. symlinks. This should be rare.
    239   *
    240   * This will definitely fail on an OS before Windows 10 build 1809
    241   * (October 2018 Update).
    242   *
    243   * NOTE: Can only run on the main thread, but the actual work occurs on a
    244   * background thread.
    245   *
    246   * @throws NS_ERROR_NOT_SAME_THREAD
    247   *         if called off main thread.
    248   * @throws NS_ERROR_NOT_AVAILABLE
    249   *         if OS is not at least Windows 10 build 1809, or if creating the
    250   *         Taskband Pin object fails
    251   * @throws NS_ERROR_FAILURE
    252   *         for unexpected errors
    253   *
    254   * @rejects NS_ERROR_FILE_NOT_FOUND
    255   *         if a shortcut matching this app's AUMID and exe path wasn't found
    256   *
    257   * @returns {Promise<void>} A promise that resolves to |undefined| if
    258   *                          successful or rejects with an nserror.
    259   */
    260  [implicit_jscontext]
    261  Promise pinCurrentAppToTaskbarAsync(in boolean aPrivateBrowsing);
    262 
    263  /*
    264   * Do a dry run of pinCurrentAppToTaskbar().
    265   *
    266   * NOTE: Can only be run on the main thread, but the actual work occurs on a
    267   * background thread.
    268   *
    269   * This does all the same checks and setup, throws the same errors, but doesn't
    270   * do the final step of creating the pin.
    271   *
    272   * @throws same as pinCurrentAppToTaskbarAsync()
    273   * @rejects same as pinCurrentAppToTaskbarAsync()
    274   * @returns same as pinCurrentAppToTaskbarAsync()
    275   */
    276  [implicit_jscontext]
    277  Promise checkPinCurrentAppToTaskbarAsync(in boolean aPrivateBrowsing);
    278 
    279  /*
    280   * Search for the current executable among taskbar pins
    281   *
    282   * NOTE: Can only be run on the main thread, but the actual work occurs on a
    283   * background thread.
    284   *
    285   * NOTE: It is possible for the check to fail even when a taskbar pin refers
    286   * to this executable, if the paths differ due to e.g. symlinks.
    287   * It is also possible for the check to succeed with a shortcut that doesn't
    288   * actually appear on the taskbar.
    289   * These cases should be rare.
    290   *
    291   * @return Promise that always resolves, true if pinned, false otherwise
    292   * @throws NS_ERROR_NOT_SAME_THREAD if not run on the main thread
    293   *
    294   */
    295  [implicit_jscontext]
    296  Promise isCurrentAppPinnedToTaskbarAsync(in AString aumid);
    297 
    298  /*
    299   * Similar to createShortcut except it removes most of the checking in that
    300   * function that ensures we are pinning a Firefox executable instead allowing
    301   * any shortcut to be pinned.
    302   *
    303   * This function should not be called unless it is certain that it's
    304   * necessary given how few checks there are within.
    305   * @param  aAppUserModelId
    306   *         The aumid to be contained in the .lnk file
    307   * @param  aShortcutFolder The special Windows folder to create the shortcut
    308   *         in. Must be either "Programs" or "Desktop".
    309   * @param  aShortcutRelativePath
    310   *         The path to the .lnk file that should be pinned to the taskbar,
    311   *         relative to aShortcutFolder.
    312   */
    313  [implicit_jscontext]
    314  Promise pinShortcutToTaskbar(
    315    in AString aAppUserModelId,
    316    in AString aShortcutFolder,
    317    in AString aShortcutRelativePath
    318  );
    319 
    320  /* This function can be used to convert compatible image formats into .ico
    321   * files to be used for .lnk files (see createShortcut).
    322   *
    323   * @param  aFile
    324   *         Output file to be written
    325   * @param  aContainer
    326   *         The graphics container
    327   */
    328  [implicit_jscontext]
    329  Promise createWindowsIcon(
    330    in nsIFile aFile,
    331    in imgIContainer aContainer
    332  );
    333 
    334  /*
    335   * This function is a counterpart to pinShortcutToTaskbar and allows
    336   * the unpinning of any shortcut, including non-Firefox executables,
    337   * without the checks of createShortcut.
    338   *
    339   * This function should not be called unless it is certain that it's
    340   * necessary given how few checks there are within.
    341   * @param  aShortcutFolder The special Windows folder that the shortcut
    342   *         is in. Must be either "Programs" or "Desktop".
    343   * @param  aShortcutRelativePath
    344   *         The path to the .lnk file that should be unpinned, relative
    345   *         to aShortcutFolder.
    346   * @throws NS_ERROR_FAILURE
    347   *         If the COM service could not be initialized
    348   * @throws NS_ERROR_FILE_NOT_FOUND
    349   *         If aShortcutPath cannot be found
    350   * @throws NS_ERROR_NOT_AVAILABLE
    351   *         If the taskbar pinning service cannot be initialized
    352   * @throws NS_ERROR_FILE_ACCESS_DENIED
    353   *         If the taskbar pins cannot be modified
    354   */
    355  void unpinShortcutFromTaskbar(
    356    in AString aShortcutFolder,
    357    in AString aShortcutRelativePath
    358  );
    359 
    360  /*
    361   * Determine where a given shortcut likely appears in the shell.
    362   *
    363   * Returns one of:
    364   * - "StartMenu" or "StartMenuPrivate", Current User or All Users Start
    365   *    Menu, including pins
    366   * - "Desktop" or "DesktopPrivate", Current User or All Users Desktop
    367   * - "Taskbar" or "TaskbarPrivate", Taskbar Pins
    368   * - "" otherwise
    369   *
    370   * If a Private Browsing shortcut was used to launch, the "Private"
    371   * variant of one of the above entries will be returned.
    372   *
    373   * NOTE: This tries to avoid I/O, so paths are compared directly as
    374   * strings, which may not be accurate in all cases. It is intended
    375   * for noncritical telemetry use.
    376   */
    377  AString classifyShortcut(in AString aPath);
    378 
    379  /*
    380   * Determine whether a pinnable shortcut with matching AUMID is present.
    381   *
    382   * @param  aAUMID
    383   *         AUMID of the shortcut to find.
    384   * @param  aPrivateBrowsing
    385   *         `true` to have the private browsing suffix added to `aAUMID`.
    386   *
    387   * @returns {Promise<void>} Always resolves with boolean, true if a pinnable
    388   *                          shortcut exists.
    389   */
    390  [implicit_jscontext]
    391  Promise hasPinnableShortcut(in AString aAUMID, in boolean aPrivateBrowsing);
    392 
    393  /*
    394   * Check if setDefaultBrowserUserChoice() is expected to succeed.
    395   *
    396   * This checks the ProgIDs for this installation, and the hash of the existing
    397   * UserChoice association.
    398   *
    399   * @return true if the check succeeds, false otherwise.
    400   */
    401  boolean canSetDefaultBrowserUserChoice();
    402 
    403  /*
    404   * checkAllProgIDsExist() and checkBrowserUserChoiceHashes() are components
    405   * of canSetDefaultBrowserUserChoice(), broken out for telemetry purposes.
    406   *
    407   * @return true if the check succeeds, false otherwise.
    408   */
    409  boolean checkAllProgIDsExist();
    410  boolean checkBrowserUserChoiceHashes();
    411 
    412  /*
    413   * Retrieves the application-defined, explicit Application User Model ID
    414   * for the current process. This function is only to be used on
    415   * Windows for testing purposes
    416   *
    417   * @return string AUMID
    418   * @throws NS_ERROR_FAILURE when the AUMID cannot be fetched
    419   */
    420  AString checkCurrentProcessAUMIDForTesting();
    421 
    422  /*
    423   * Determines whether or not Firefox is the "Default Handler", i.e.,
    424   * is registered to handle, the given file extension (like ".pdf")
    425   * or protocol (like "https").
    426   */
    427  boolean isDefaultHandlerFor(in AString aFileExtensionOrProtocol);
    428 
    429 
    430  /*
    431   * Return the Windows ProgID currently registered to handle the gven
    432   * file extension (like ".pdf") or protocol (like "https").
    433   *
    434   * @return string ProgID, or "" when no association is registered.
    435   * @throws NS_ERROR_FAILURE when the file extension or protocol
    436   *         cannot be determined.
    437   */
    438  AString queryCurrentDefaultHandlerFor(in AString aFileExtensionOrProtocol);
    439 };