Skip to content

feat: support virtual and MTP mobile device items preview - #1995

Open
StevenWin818 wants to merge 1 commit into
QL-Win:masterfrom
StevenWin818:master
Open

feat: support virtual and MTP mobile device items preview#1995
StevenWin818 wants to merge 1 commit into
QL-Win:masterfrom
StevenWin818:master

Conversation

@StevenWin818

@StevenWin818 StevenWin818 commented Aug 30, 2026

Copy link
Copy Markdown

PR Checklist

  • Functionality has been tested, no obvious bugs
  • Code style follows project conventions
  • Documentation/comments updated (if applicable)

Brief Description of Changes

This PR adds safe metadata previews for non-filesystem Windows Shell items, including MTP mobile-device files and folders.

  • Prefer SIGDN_FILESYSPATH for normal filesystem selections.
  • Preserve the Explorer-resolved PIDL for virtual items and collect their display name, size, modification time, canonical parsing identity, and system icon index.
  • Route virtual items directly to the built-in InfoPanel without passing Shell parsing names to existing file-based plugins.
  • Display virtual-item metadata and the corresponding jumbo system icon without treating the item as a filesystem path.
  • Compare virtual selections by canonical parsing identity so metadata changes do not cause repeated preview requests.
  • Scope COM initialization and release native icon and COM resources deterministically.

Related Issue (if any)

Fixes #1769

Additional Notes

  • This PR provides a metadata and system-icon preview for virtual/MTP items; it does not copy or materialize their file contents.
  • Existing filesystem paths and pure desktop CLSID items retain their existing preview behavior.
  • No external dependencies were added.
  • The changes have been built and manually tested on Windows amd64.

Summary by Sourcery

Support safe previews for virtual and MTP Windows Shell items without treating them as filesystem paths.

New Features:

  • Add metadata and system-icon previews for virtual Windows Shell items, including MTP mobile-device files and folders.
  • Route virtual selections to the built-in InfoPanel while preserving existing filesystem and CLSID preview behavior.

Bug Fixes:

  • Prevent virtual-item metadata changes from triggering redundant preview requests by comparing canonical identities.
  • Avoid passing virtual Shell parsing names to file-based plugins and suppress unsupported virtual-item actions.

Enhancements:

  • Improve Shell selection handling with filesystem-path preference, virtual-item identity preservation, and deterministic COM and native-resource cleanup.

@sourcery-ai

sourcery-ai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR adds an end-to-end virtual Shell-item preview path: native code identifies filesystem versus virtual selections and serializes safe metadata, managed code preserves and compares their canonical identities, and the viewer routes them to an InfoPanel that renders metadata and the corresponding system icon without exposing Shell parsing names to file-based plugins.

Sequence diagram for virtual Shell item preview

sequenceDiagram
    participant Explorer
    participant NativeSelection as NativeSelection
    participant FocusMonitor
    participant ViewWindowManager
    participant InfoPanel
    participant ShellIcon as ShellIcon

    Explorer->>NativeSelection: GetCurrentSelection()
    NativeSelection->>NativeSelection: GetDisplayName(SIGDN_FILESYSPATH)
    alt virtual or MTP item
        NativeSelection->>NativeSelection: GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING)
        NativeSelection->>NativeSelection: FormatVirtualItem()
        NativeSelection-->>FocusMonitor: ::QL_VIRTUAL metadata
        FocusMonitor->>FocusMonitor: VirtualItemInfo.IsSameItem()
        FocusMonitor->>ViewWindowManager: SendMessage(Switch, path)
        ViewWindowManager->>InfoPanel: DisplayInfo(path)
        InfoPanel->>InfoPanel: VirtualItemInfo.TryParse(path)
        InfoPanel->>ShellIcon: GetJumboIcon(iconIndex)
        ShellIcon-->>InfoPanel: BitmapSource
    end
Loading

File-Level Changes

Change Details Files
Add native extraction and serialization of metadata for non-filesystem Shell selections while preserving normal filesystem and CLSID handling.
  • Prefer filesystem display names for regular items.
  • Serialize virtual item name, size, modification time, icon index, and parsing identity into a dedicated marker format.
  • Use the Explorer-resolved PIDL to obtain the system icon index.
  • Manage COM initialization, Shell allocations, and drag-drop resources deterministically.
QuickLook.Native/QuickLook.Native32/HelperMethods.cpp
QuickLook.Native/QuickLook.Native32/Shell32.cpp
QuickLook.Native/QuickLook.Native32/stdafx.h
Introduce managed parsing and identity comparison for virtual-item metadata.
  • Parse the native marker format into display, size, date, icon, and canonical parsing-name fields.
  • Compare virtual selections by parsing identity while retaining ordinary string comparison for other paths.
  • Bypass shortcut resolution for serialized virtual selections.
QuickLook/NativeMethods/QuickLook.cs
QuickLook/FocusMonitor.cs
Route virtual selections through the built-in InfoPanel instead of filesystem-oriented plugins.
  • Force virtual items to the default viewer and restrict plugin invocation to physical paths.
  • Treat virtual items as previewable without requiring File.Exists or Directory.Exists.
  • Prevent reload and plugin controls/actions that require a filesystem path.
QuickLook/PluginManager.cs
QuickLook/ViewWindowManager.cs
QuickLook/ViewerWindow.Actions.cs
Render virtual-item metadata and jumbo Shell icons in the InfoPanel.
  • Display virtual names, optional size, and localized modification timestamps.
  • Retrieve jumbo icons from the system image list and release icon and COM resources.
  • Reset stale image state before rendering virtual or regular content.
QuickLook/Plugin/InfoPanel/InfoPanel.xaml.cs
QuickLook/Plugin/InfoPanel/WindowsThumbnailProvider.cs

Assessment against linked issues

Issue Objective Addressed Explanation
#1769 Prevent QuickLook from crashing when selecting files or folders from MTP and other non-filesystem Windows Shell locations.
#1769 Support safe previews for virtual and MTP items without passing their Shell parsing names to filesystem-based thumbnail or preview code.
#1769 Provide useful metadata and icon information for virtual/MTP selections while preserving existing behavior for normal filesystem items and CLSID shell items.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="QuickLook/Plugin/InfoPanel/WindowsThumbnailProvider.cs" line_range="50-52" />
<code_context>
+    private const int IldTransparent = 0x00000001;
+    private static readonly Guid IidImageList = new("46EB5926-582E-4017-9FDF-E8998DAA0950");
+
+    [ComImport, Guid("46EB5926-582E-4017-9FDF-E8998DAA0950"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+    private interface IImageList
+    {
+        [PreserveSig] int _0(); [PreserveSig] int _1(); [PreserveSig] int _2(); [PreserveSig] int _3();
+        [PreserveSig] int _4(); [PreserveSig] int _5(); [PreserveSig] int _6();
+        [PreserveSig] int GetIcon(int i, int flags, out IntPtr picon);
+    }
+
</code_context>
<issue_to_address>
**issue (bug_risk):** `IImageList.GetIcon` is declared at the eighth COM vtable slot, but the native `IImageList` interface has additional methods before `GetIcon` (including `GetImageInfo`, `Copy`, `Merge`, and `Clone`). The call therefore dispatches to the wrong method and can fail to return an icon or corrupt memory when a virtual item preview requests its jumbo icon.

**Triggers:** When a virtual item has a non-negative system icon index and `GetJumboIcon` calls `imageList.GetIcon`.

**Suggested fix:** Declare all preceding `IImageList` methods so `GetIcon` occupies its correct COM vtable slot, or use a correctly defined interop interface.

```suggestion
        [PreserveSig] int GetImageCount(out int pCount);
        [PreserveSig] int SetImageCount(int uNewCount);
        [PreserveSig] int GetImageInfo(int i, IntPtr pImageInfo);
        [PreserveSig] int Copy(int iDst, int iSrc, int uFlags);
        [PreserveSig] int Merge(int i1, int i2, IntPtr ppim, int dx, int dy);
        [PreserveSig] int Clone(IntPtr ppim);
        [PreserveSig] int Draw(IntPtr pimldp);
        [PreserveSig] int GetIcon(int i, int flags, out IntPtr picon);
```
</issue_to_address>

### Comment 2
<location path="QuickLook.Native/QuickLook.Native32/HelperMethods.cpp" line_range="164" />
<code_context>
+            ATL::CComHeapPtr<WCHAR> filePath;
+            if (SUCCEEDED(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)) && filePath)
+            {
+                StringCchCopyW(buffer, MAX_PATH_EX, filePath);
+            }
+            else
</code_context>
<issue_to_address>
**issue (bug_risk):** The filesystem-path branch copies the `SIGDN_FILESYSPATH` result with a `MAX_PATH` capacity instead of `MAX_PATH_EX`. Long filesystem selections are truncated or cause `StringCchCopyW` to fail, leaving the selection buffer unusable even though the native API and the surrounding code support extended-length paths.

**Triggers:** When a normal filesystem selection has a path longer than 260 characters.

**Suggested fix:** Pass `MAX_PATH_EX` to `StringCchCopyW` in this branch and handle a failed copy consistently.

```suggestion
                if (FAILED(StringCchCopyW(buffer, MAX_PATH_EX, filePath)))
                    buffer[0] = L'\0';
```
</issue_to_address>

Sourcery assessment

Approval pending. 2 findings to address first.

Blocking findings: QuickLook/Plugin/InfoPanel/WindowsThumbnailProvider.cs:52, QuickLook.Native/QuickLook.Native32/HelperMethods.cpp:164


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread QuickLook/Plugin/InfoPanel/WindowsThumbnailProvider.cs
Comment thread QuickLook.Native/QuickLook.Native32/HelperMethods.cpp Outdated
sourcery-ai[bot]
sourcery-ai Bot previously approved these changes Aug 30, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sourcery assessment

Approved.

@StevenWin818
StevenWin818 force-pushed the master branch 2 times, most recently from 8a3581e to 123fb8c Compare August 30, 2026 08:05
@sourcery-ai
sourcery-ai Bot dismissed their stale review August 30, 2026 08:05

Sourcery withdrew this approval because the latest commits introduced blocking findings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Exception when opening QuickLook on files from a connected media device

1 participant