From 95f4a2923269c8799f5e5cec853b8c43cc393ef5 Mon Sep 17 00:00:00 2001 From: antmor <43587397+antmor@users.noreply.github.com> Date: Fri, 10 Jul 2026 21:44:49 -0700 Subject: [PATCH 1/3] Add RAII (ILFree) annotation for PIDL types so CsWin32 generates a SafeHandle Model PIDLIST_RELATIVE, PIDLIST_ABSOLUTE, and PITEMID_CHILD as NativeTypedef handles with CloseApi=ILFree in autoTypes.json, following the HLOCAL/HGLOBAL (void* + free-function) precedent. This lets CsWin32 emit an ILFree-based SafeHandle for PIDLs instead of requiring consumers to hand-roll RAII around SHGetIDListFromObject, ILCreateFromPath, SHGetKnownFolderIDList, etc. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- generation/WinSDK/autoTypes.json | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/generation/WinSDK/autoTypes.json b/generation/WinSDK/autoTypes.json index 4bd05fe3..53290495 100644 --- a/generation/WinSDK/autoTypes.json +++ b/generation/WinSDK/autoTypes.json @@ -446,6 +446,32 @@ "InvalidHandleValues": [ -1, 0 ], "NativeTypedef": true }, + { + "Namespace": "Windows.Win32.UI.Shell.Common", + "Name": "PIDLIST_RELATIVE", + "ValueType": "void*", + "CloseApi": "ILFree", + "InvalidHandleValues": [ 0 ], + "NativeTypedef": true + }, + { + "Namespace": "Windows.Win32.UI.Shell.Common", + "Name": "PIDLIST_ABSOLUTE", + "ValueType": "void*", + "CloseApi": "ILFree", + "AlsoUsableFor": "PIDLIST_RELATIVE", + "InvalidHandleValues": [ 0 ], + "NativeTypedef": true + }, + { + "Namespace": "Windows.Win32.UI.Shell.Common", + "Name": "PITEMID_CHILD", + "ValueType": "void*", + "CloseApi": "ILFree", + "AlsoUsableFor": "PIDLIST_RELATIVE", + "InvalidHandleValues": [ 0 ], + "NativeTypedef": true + }, { "Name": "HCOLORSPACE", "ValueType": "DECLARE_HANDLE", From 5f6d49e560c12ffb78c0b3b201617d8a18e3a902 Mon Sep 17 00:00:00 2001 From: antmor <43587397+antmor@users.noreply.github.com> Date: Fri, 10 Jul 2026 21:44:49 -0700 Subject: [PATCH 2/3] Rework PIDL RAII to BSTR-style typedef; add FreeWith(CoTaskMemFree) for string out-params - PIDL typedefs (PIDLIST_RELATIVE/ABSOLUTE, PITEMID_CHILD) now follow the BSTR pattern: NativeTypedef wrapping the real ITEMIDLIST* pointee (no void*) with CloseApi=CoTaskMemFree, so CsWin32 generates a strongly-typed SafeHandle. Namespace is inherited from the CloseApi (as BSTR/HANDLE do). - Add FreeWith(CoTaskMemFree) annotations for PWSTR/LPOLESTR out-params that must be freed with CoTaskMemFree (the unique_cotaskmem_string cases): SHGetNameFromIDList, StringFromCLSID, StringFromIID, IShellItem::GetDisplayName. Mirrors the existing SHGetKnownFolderPath::ppszPath precedent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- generation/WinSDK/autoTypes.json | 18 ++++++------------ generation/WinSDK/emitter.settings.rsp | 4 ++++ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/generation/WinSDK/autoTypes.json b/generation/WinSDK/autoTypes.json index 53290495..c9e877eb 100644 --- a/generation/WinSDK/autoTypes.json +++ b/generation/WinSDK/autoTypes.json @@ -447,29 +447,23 @@ "NativeTypedef": true }, { - "Namespace": "Windows.Win32.UI.Shell.Common", "Name": "PIDLIST_RELATIVE", - "ValueType": "void*", - "CloseApi": "ILFree", - "InvalidHandleValues": [ 0 ], + "ValueType": "Windows.Win32.UI.Shell.Common.ITEMIDLIST*", + "CloseApi": "CoTaskMemFree", "NativeTypedef": true }, { - "Namespace": "Windows.Win32.UI.Shell.Common", "Name": "PIDLIST_ABSOLUTE", - "ValueType": "void*", - "CloseApi": "ILFree", + "ValueType": "Windows.Win32.UI.Shell.Common.ITEMIDLIST*", + "CloseApi": "CoTaskMemFree", "AlsoUsableFor": "PIDLIST_RELATIVE", - "InvalidHandleValues": [ 0 ], "NativeTypedef": true }, { - "Namespace": "Windows.Win32.UI.Shell.Common", "Name": "PITEMID_CHILD", - "ValueType": "void*", - "CloseApi": "ILFree", + "ValueType": "Windows.Win32.UI.Shell.Common.ITEMIDLIST*", + "CloseApi": "CoTaskMemFree", "AlsoUsableFor": "PIDLIST_RELATIVE", - "InvalidHandleValues": [ 0 ], "NativeTypedef": true }, { diff --git a/generation/WinSDK/emitter.settings.rsp b/generation/WinSDK/emitter.settings.rsp index 45cdad2e..f39e484c 100644 --- a/generation/WinSDK/emitter.settings.rsp +++ b/generation/WinSDK/emitter.settings.rsp @@ -262,6 +262,10 @@ SHFormatDrive::fmtID=SHFMT_ID SHGetSetSettings::dwMask=SSF_MASK IStream::Seek::dwOrigin=STREAM_SEEK SHGetKnownFolderPath::ppszPath=[FreeWith("CoTaskMemFree")] +SHGetNameFromIDList::ppszName=[FreeWith("CoTaskMemFree")] +StringFromCLSID::lplpsz=[FreeWith("CoTaskMemFree")] +StringFromIID::lplpsz=[FreeWith("CoTaskMemFree")] +IShellItem::GetDisplayName::ppszName=[FreeWith("CoTaskMemFree")] PSINJECTDATA::InjectionPoint=PSINJECT_POINT EnumObjects::nType=OBJ_TYPE EnumSystemFirmwareTables::pFirmwareTableEnumBuffer=byte* From dcdb80b99a777c8f7ed301bb55de71a80a89eed7 Mon Sep 17 00:00:00 2001 From: antmor <43587397+antmor@users.noreply.github.com> Date: Fri, 10 Jul 2026 22:32:37 -0700 Subject: [PATCH 3/3] Fix namespace cycle: co-locate PIDL typedefs and ILFree in Shell.Common Placing the PIDL NativeTypedefs in the CloseApi's inherited namespace put them in System.Com while their ITEMIDLIST* payload lives in Shell.Common, creating a System.Com <-> Shell.Common cycle (NoCyclicalNamespaces failure). Fix keeps the strong ITEMIDLIST* typing by co-locating everything in Shell.Common: - PIDL typedefs (PIDLIST_RELATIVE/ABSOLUTE, PITEMID_CHILD) explicitly in Windows.Win32.UI.Shell.Common with ValueType=ITEMIDLIST* and CloseApi=ILFree. - Move ILFree into Shell.Common via requiredNamespacesForNames.rsp so the CloseApi is intra-namespace (satisfies the same-namespace rule, adds no outward edge). - Restore InvalidHandleValues=[0] (required by RaiiFreeAttributeTests). Validated locally against MSVC 14.44: all tests pass (MetadataUtils 17/17, Win32MetadataScraper 44/44, Windows.Win32.Tests 13/13). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- generation/WinSDK/autoTypes.json | 18 ++++++++++++------ .../WinSDK/requiredNamespacesForNames.rsp | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/generation/WinSDK/autoTypes.json b/generation/WinSDK/autoTypes.json index c9e877eb..48799f49 100644 --- a/generation/WinSDK/autoTypes.json +++ b/generation/WinSDK/autoTypes.json @@ -447,23 +447,29 @@ "NativeTypedef": true }, { + "Namespace": "Windows.Win32.UI.Shell.Common", "Name": "PIDLIST_RELATIVE", - "ValueType": "Windows.Win32.UI.Shell.Common.ITEMIDLIST*", - "CloseApi": "CoTaskMemFree", + "ValueType": "ITEMIDLIST*", + "CloseApi": "ILFree", + "InvalidHandleValues": [ 0 ], "NativeTypedef": true }, { + "Namespace": "Windows.Win32.UI.Shell.Common", "Name": "PIDLIST_ABSOLUTE", - "ValueType": "Windows.Win32.UI.Shell.Common.ITEMIDLIST*", - "CloseApi": "CoTaskMemFree", + "ValueType": "ITEMIDLIST*", + "CloseApi": "ILFree", "AlsoUsableFor": "PIDLIST_RELATIVE", + "InvalidHandleValues": [ 0 ], "NativeTypedef": true }, { + "Namespace": "Windows.Win32.UI.Shell.Common", "Name": "PITEMID_CHILD", - "ValueType": "Windows.Win32.UI.Shell.Common.ITEMIDLIST*", - "CloseApi": "CoTaskMemFree", + "ValueType": "ITEMIDLIST*", + "CloseApi": "ILFree", "AlsoUsableFor": "PIDLIST_RELATIVE", + "InvalidHandleValues": [ 0 ], "NativeTypedef": true }, { diff --git a/generation/WinSDK/requiredNamespacesForNames.rsp b/generation/WinSDK/requiredNamespacesForNames.rsp index dbcff5db..b3a2c56a 100644 --- a/generation/WinSDK/requiredNamespacesForNames.rsp +++ b/generation/WinSDK/requiredNamespacesForNames.rsp @@ -669,6 +669,7 @@ IADesktopP2=Windows.Win32.UI.LegacyWindowsEnvironmentFeatures DoPrivacyDlg=Windows.Win32.Web.MsHtml # endregion shlobj.h # region shlobj_core.h +ILFree=Windows.Win32.UI.Shell.Common PROPERTYUI_FLAGS=Windows.Win32.UI.Shell.PropertiesSystem PROPERTYUI_NAME_FLAGS=Windows.Win32.UI.Shell.PropertiesSystem PROPERTYUI_FORMAT_FLAGS=Windows.Win32.UI.Shell.PropertiesSystem