You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SHGetFileInfoW needs a binary-PIDL input overload for SHGFI_PIDL #1832
SHGetFileInfoW needs a binary-PIDL input overload for SHGFI_PIDL
Summary
When SHGFI_PIDL is set, the first argument of SHGetFileInfoW is a binary ITEMIDLIST pointer, not a UTF-16 path. CsWin32 projects that argument as PCWSTR and offers friendly string overloads, but no overload that accepts
binary PIDL bytes (for example, ReadOnlySpan<byte>).
The generated overload taking Span<byte> uses it for the third, output SHFILEINFOW parameter; it does not solve the binary first parameter.
See the Win32 SHGetFileInfoW documentation.
Reproduction
With CsWin32 0.3.335, request SHGetFileInfo in NativeMethods.txt and use
an absolute PIDL such as the two-byte Desktop/root PIDL:
The explicit byte* -> char* -> PCWSTR reinterpretation is required to
compile. Replacing the first argument with desktopPidl, desktopPidl.AsSpan(),
or a string is not an equivalent safe option: the PIDL is binary data with
embedded zero bytes, not a text path.
The generated method shapes observed in the consuming assembly are:
Please provide a friendly overload accepting a binary PIDL input such as ReadOnlySpan<byte> (also usable from Span<byte>), pinning it for the call
and forwarding it as the first argument when SHGFI_PIDL is specified.
The overload should keep the existing path/string behavior for calls without SHGFI_PIDL; no conversion of the PIDL bytes to text is appropriate.
This would let callers of the dual-purpose API use the correct representation
without hand-writing an unsafe pointer reinterpretation or suppressing
native-interop analyzer warnings.
Follow-up research: this appears to be one instance of a broader Win32 metadata problem where a parameter is declared as a string pointer for ABI purposes but can conditionally carry some other value or pointer type.
API/surface
Declared type
Alternate interpretation
SHGetFileInfo with SHGFI_PIDL
PCWSTR
ITEMIDLIST*
GetModuleHandleEx with GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
PCWSTR
An arbitrary address within the module
CreateWindowEx.lpClassName
PCWSTR
ATOM
Resource APIs and fields
PCWSTR
A MAKEINTRESOURCE identifier
TaskDialog.pszIcon
PCWSTR
A predefined icon identifier
OPENFILENAME.lpTemplateName
PCWSTR
A resource identifier
Relevant Win32Metadata history:
microsoft/win32metadata#69 handled MAKEINTRESOURCE from the constant/value side. Constants are emitted as ushort with [NativeTypeName("LPCWSTR")] or LPCSTR, but this does not identify which parameters or fields accept such values.
microsoft/win32metadata#623 discussed this exact shape for CreateWindowEx accepting either a string or an ATOM. A native union was rejected because wrapping a pointer may alter ABI behavior. Possible annotations such as an opaque union or unaligned pointer were discussed, but the information was ultimately left to individual projections.
microsoft/win32metadata#2160 confirms that Win32Metadata currently has no mechanism to model the alternate interpretations of SHGetFileInfo.pszPath.
[AssociatedEnum] is the nearest existing metadata pattern: it retains the header/ABI type while identifying another logical type that projections may expose. There is no corresponding general [AssociatedType]/[AcceptsType] annotation today.
A potential general solution would be a repeatable parameter/field annotation such as [AcceptsType("ITEMIDLIST*")], preserving the original ABI type while allowing projections to generate appropriate alternatives. APIs whose interpretation is flag-dependent may additionally need a way to associate the alternate type with SHGFI_PIDL, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, etc.
For this particular API, metadata should probably express the alternate native type as ITEMIDLIST*; projecting that as a friendly ReadOnlySpan<byte> overload would then be CsWin32 policy.
Activity
jevansaks commentedon Sep 29, 2026
Follow-up research: this appears to be one instance of a broader Win32 metadata problem where a parameter is declared as a string pointer for ABI purposes but can conditionally carry some other value or pointer type.
SHGetFileInfowithSHGFI_PIDLPCWSTRITEMIDLIST*GetModuleHandleExwithGET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESSPCWSTRCreateWindowEx.lpClassNamePCWSTRATOMPCWSTRMAKEINTRESOURCEidentifierTaskDialog.pszIconPCWSTROPENFILENAME.lpTemplateNamePCWSTRRelevant Win32Metadata history:
MAKEINTRESOURCEfrom the constant/value side. Constants are emitted asushortwith[NativeTypeName("LPCWSTR")]orLPCSTR, but this does not identify which parameters or fields accept such values.CreateWindowExaccepting either a string or anATOM. A native union was rejected because wrapping a pointer may alter ABI behavior. Possible annotations such as an opaque union or unaligned pointer were discussed, but the information was ultimately left to individual projections.SHGetFileInfo.pszPath.[AssociatedEnum]is the nearest existing metadata pattern: it retains the header/ABI type while identifying another logical type that projections may expose. There is no corresponding general[AssociatedType]/[AcceptsType]annotation today.A potential general solution would be a repeatable parameter/field annotation such as
[AcceptsType("ITEMIDLIST*")], preserving the original ABI type while allowing projections to generate appropriate alternatives. APIs whose interpretation is flag-dependent may additionally need a way to associate the alternate type withSHGFI_PIDL,GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, etc.For this particular API, metadata should probably express the alternate native type as
ITEMIDLIST*; projecting that as a friendlyReadOnlySpan<byte>overload would then be CsWin32 policy.E021ntox commentedon Oct 3, 2026
Another issue is that
&infotriggers a warning:CS9123: The '&' operator should not be used on parameters or local variables in async methods.jevansaks commentedon Oct 5, 2026
That's easy to handle in these cases by lifting the unsafe block into a sync method.
E021ntox commentedon Oct 15, 2026
Jevan Saks (@jevansaks) I reported this issue in win32metadata about a month ago, but haven't received a response yet, so I'm following up here.
IImageList::GetIconshould also useIMAGE_LIST_DRAW_STYLEhttps://learn.microsoft.com/en-us/windows/win32/api/commoncontrols/nf-commoncontrols-iimagelist-geticon
jevansaks commentedon Oct 15, 2026
E021ntox You commented on a closed issue, that makes it easier to miss. If you have a specific request, please file a new issue on win32metadata.