http://bugs.winehq.org/show_bug.cgi?id=60295 --- Comment #1 from TOP <kellnerp@earthlink.net> --- Comment for https://bugs.winehq.org/show_bug.cgi?id=39773 --- Ran into this same issue (uncached `desktop.ini` lookup in `SHELL32_GetCustomFolderAttributeFromPath()`) via a different real-world trigger than the original report, and did a fairly deep investigation that I think adds useful evidence. Posting a summary; happy to attach the reproduction source files if useful. **Real-world trigger:** Insta360 Studio 2022 (Qt5-based app running under Wine), when shift-click range-selecting a large sequence of files (~1000 interval/timelapse photos) in its file browser. No network share needed to reproduce the severity — a local filesystem with a moderately deep path (~10 components) and a large selection is enough to turn this into a multi-minute apparent hang requiring force-quit. **Confirmed mechanism (two independent live backtraces via `winedbg --gdb` on the hung process):** Main UI thread found blocked in `NtCreateFile`, with the following call chain (frame numbers as captured; some `SHELL32_BindToChild` recursion frames omitted for brevity): ``` NtCreateFile -> CreateFileW dlls/kernelbase/file.c:873 -> PROFILE_Open dlls/kernel32/profile.c:764 -> GetPrivateProfileStringW dlls/kernel32/profile.c:1422 -> SHELL32_GetCustomFolderAttributeFromPath dlls/shell32/shlfolder.c:75 -> SHELL32_BindToChild (recursing, once per path component) -> ShellItem_get_parent_shellfolder dlls/shell32/shellitem.c:165 -> ShellItem_GetAttributes dlls/shell32/shellitem.c:285 -> [caller in platforms/qwindows.dll -- Qt5 platform plugin] ``` Confirmed twice, independently, on different sessions/paths -- same mechanism both times. **Source-level confirmation of why this compounds so badly:** in `dlls/shell32/shlview.c`, `LV_AddItem()` inserts list items with: ```c lvItem.pszText = LPSTR_TEXTCALLBACKW; /* get text on a callback basis */ lvItem.iImage = I_IMAGECALLBACK; /* get the image on a callback basis */ ``` i.e. the ListView is populated in owner-data/callback mode. It does not hold display data -- it re-requests it via `LVN_GETDISPINFO` every time it needs to *show* an item (initial paint, scroll, selection-state change, any redraw). Each of those callbacks resolves through the shell folder, hitting the uncached `desktop.ini` walk again. This means the real-world cost isn't "N files x path-depth" as a single pass -- it's that multiplied again by however many times the UI redraws each visible item during the operation. **Quantitative confirmation**, using a 1000-file/10-level-deep synthetic test tree (fully synthetic, reproducible without Insta360): | Test | Per-item cost | Notes | |---|---|---| | Headless console app, single `IShellItem::GetAttributes()` call per file, no UI | 2.1 ms | Baseline: raw uncached-lookup cost only | | Custom listview replicating shlview.c's exact `LPSTR_TEXTCALLBACKW` pattern, `strace`'d | ~399 `openat` syscalls/file | Manual real interaction (shift-click), not automated | | Real `GetOpenFileNameW()` dialog (Wine's actual comdlg32/shell32), manual shift-click | ~76 ms/item | Two independently-built repro programs converge on ~76-77ms/item and similar syscall-count order of magnitude | | Real Insta360 Studio, live process, `strace`'d during actual hang | ~534 `openat` syscalls/file, ~750ms/item wall time | 947-file real selection | The call-count order of magnitude (mid-hundreds of opens per file) is consistent across three independently-measured sources: the real app, a minimal custom owner-data listview, and the real Wine common dialog. The residual gap between synthetic repro wall-time (~76ms/item) and the real app (~750ms/item) is most likely wineserver round-trip contention from Studio's ~80 background threads competing for the same serialized socket during selection -- not reproducible in an isolated single-process test by design, and not needed to explain the core mechanism or its severity. **Confirms this comment's suggested fix (from the original report) still applies and is the right fix:** caching `SHELL32_GetCustomFolderAttributeFromPath()`'s result per directory (rather than returning FALSE unconditionally, which would break legitimate custom-folder-icon support) would collapse the repeated-lookup cost to one real check per unique directory for the lifetime of a shell operation, regardless of how many times the owner-data listview re-queries display info per item. This matches how native Windows Explorer behaves (per the original report: "when displaying a filename we have everything in the cache so redisplays are lightning fast"). Still reproducible on current Wine (tested on 11.0), a decade after the original report -- this remains an open, real-world-impacting issue. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.