From f510b2d32e23dc1c92084523879a377f53128abf Mon Sep 17 00:00:00 2001 From: dahall Date: Sun, 12 Jul 2020 14:09:40 -0600 Subject: [PATCH] For all COM IEnumXX interfaces, fixed the Next method's array parameter so that it references the size on input, not output. This prevents a bug when implementing these interfaces. Thanks to @wangfu91 for finding this and submitting #143. --- PInvoke/Graphics/WIC/WindowsCodecs.Interfaces2.cs | 4 +++- PInvoke/Ole/Ole32/ComCat.cs | 4 ++-- PInvoke/Ole/Ole32/ObjIdl.cs | 6 +++--- PInvoke/Ole/Ole32/OleIdl.cs | 2 +- PInvoke/Ole/Ole32/PropIdl.cs | 4 ++-- PInvoke/Ole/OleAut32/Wia_xp.cs | 8 ++++---- PInvoke/SearchApi/SearchApi.cs | 4 ++-- PInvoke/Shell32/ShObjIdl.IAssocHandler.cs | 2 +- PInvoke/Shell32/ShObjIdl.IEnumObjects.cs | 2 +- PInvoke/Shell32/ShObjIdl.IExplorerCommand.cs | 2 +- PInvoke/Shell32/ShObjIdl.IShellFolder.cs | 2 +- PInvoke/Shell32/ShObjIdl.IShellItem.cs | 2 +- PInvoke/Shell32/ShObjIdl.IShellItemResources.cs | 2 +- PInvoke/Shell32/ShObjIdl.cs | 4 ++-- 14 files changed, 25 insertions(+), 23 deletions(-) diff --git a/PInvoke/Graphics/WIC/WindowsCodecs.Interfaces2.cs b/PInvoke/Graphics/WIC/WindowsCodecs.Interfaces2.cs index 0d827e16..d8cb58a8 100644 --- a/PInvoke/Graphics/WIC/WindowsCodecs.Interfaces2.cs +++ b/PInvoke/Graphics/WIC/WindowsCodecs.Interfaces2.cs @@ -142,7 +142,9 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/win32/api/wincodec/nf-wincodec-iwicenummetadataitem-next HRESULT Next( ULONG celt, // PROPVARIANT *rgeltSchema, PROPVARIANT *rgeltId, PROPVARIANT *rgeltValue, ULONG *pceltFetched ); [PreserveSig] - HRESULT Next(uint celt, [In, Out, Optional] PROPVARIANT_IMMUTABLE[] rgeltSchema, [In, Out] PROPVARIANT_IMMUTABLE[] rgeltId, [In, Out, Optional] PROPVARIANT_IMMUTABLE[] rgeltValue, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Optional] PROPVARIANT_IMMUTABLE[] rgeltSchema, + [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] PROPVARIANT_IMMUTABLE[] rgeltId, + [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Optional] PROPVARIANT_IMMUTABLE[] rgeltValue, out uint pceltFetched); /// Skips to given number of objects. /// diff --git a/PInvoke/Ole/Ole32/ComCat.cs b/PInvoke/Ole/Ole32/ComCat.cs index 22a0b810..7bf965f6 100644 --- a/PInvoke/Ole/Ole32/ComCat.cs +++ b/PInvoke/Ole/Ole32/ComCat.cs @@ -220,7 +220,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/win32/api/comcat/nf-comcat-ienumcategoryinfo-next HRESULT Next( ULONG celt, // CATEGORYINFO *rgelt, ULONG *pceltFetched ); [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] CATEGORYINFO[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] CATEGORYINFO[] rgelt, out uint pceltFetched); /// Skips over the specified number of items in the enumeration sequence. /// The number of items to be skipped. @@ -277,7 +277,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/win32/api/comcat/nf-comcat-ienumguid-next HRESULT Next( ULONG celt, GUID *rgelt, // ULONG *pceltFetched ); [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Guid[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] Guid[] rgelt, out uint pceltFetched); /// Skips over the specified number of items in the enumeration sequence. /// The number of items to be skipped. diff --git a/PInvoke/Ole/Ole32/ObjIdl.cs b/PInvoke/Ole/Ole32/ObjIdl.cs index e02ae6c9..685f126f 100644 --- a/PInvoke/Ole/Ole32/ObjIdl.cs +++ b/PInvoke/Ole/Ole32/ObjIdl.cs @@ -1106,7 +1106,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/desktop/api/objidl/nf-objidl-ienumcontextprops-next HRESULT Next( ULONG celt, // ContextProperty *pContextProperties, ULONG *pceltFetched ); [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] ContextProperty[] pContextProperties, + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ContextProperty[] pContextProperties, out uint pceltFetched); /// Skips over the specified number of items in the enumeration sequence. @@ -1173,7 +1173,7 @@ namespace Vanara.PInvoke /// [PreserveSig, MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] HRESULT Next([In] uint celt, - [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] STATSTG[] rgelt, + [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] STATSTG[] rgelt, out uint pceltFetched); /// Skips a specified number of STATSTG structures in the enumeration sequence. @@ -1225,7 +1225,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/desktop/api/objidl/nf-objidl-ienumunknown-next HRESULT Next( ULONG celt, IUnknown // **rgelt, ULONG *pceltFetched ); [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] IntPtr[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] rgelt, out uint pceltFetched); /// Skips over the specified number of items in the enumeration sequence. /// The number of items to be skipped. diff --git a/PInvoke/Ole/Ole32/OleIdl.cs b/PInvoke/Ole/Ole32/OleIdl.cs index bba9688c..b7c51700 100644 --- a/PInvoke/Ole/Ole32/OleIdl.cs +++ b/PInvoke/Ole/Ole32/OleIdl.cs @@ -918,7 +918,7 @@ namespace Vanara.PInvoke [PInvokeData("oleidl.h", MSDNShortId = "bb934017-9054-42b5-89d4-a24f12829503")] [PreserveSig, MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] HRESULT Next([In] uint celt, - [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] OLEVERB[] rgelt, + [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] OLEVERB[] rgelt, out uint pceltFetched); /// Skips over the specified number of items in the enumeration sequence. diff --git a/PInvoke/Ole/Ole32/PropIdl.cs b/PInvoke/Ole/Ole32/PropIdl.cs index 80c6bda8..52ea2e79 100644 --- a/PInvoke/Ole/Ole32/PropIdl.cs +++ b/PInvoke/Ole/Ole32/PropIdl.cs @@ -146,7 +146,7 @@ namespace Vanara.PInvoke // STATPROPSETSTG *rgelt, ULONG *pceltFetched ); [PInvokeData("propidl.h", MSDNShortId = "3af3c518-3db4-4436-b1c1-86587ce8fbf3")] [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] STATPROPSETSTG[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] STATPROPSETSTG[] rgelt, out uint pceltFetched); /// The Skip method skips a specified number of STATPROPSETSTG structures in the enumeration sequence. /// The number of STATPROPSETSTG structures to skip. @@ -232,7 +232,7 @@ namespace Vanara.PInvoke // STATPROPSTG *rgelt, ULONG *pceltFetched ); [PInvokeData("propidl.h", MSDNShortId = "8e911da9-0056-4267-b9d0-c4ba929ddb94")] [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] STATPROPSTG[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] STATPROPSTG[] rgelt, out uint pceltFetched); /// The Skip method skips the specified number of STATPROPSTG structures in the enumeration sequence. /// The number of STATPROPSTG structures to skip. diff --git a/PInvoke/Ole/OleAut32/Wia_xp.cs b/PInvoke/Ole/OleAut32/Wia_xp.cs index 9d000e7d..1abf0e0d 100644 --- a/PInvoke/Ole/OleAut32/Wia_xp.cs +++ b/PInvoke/Ole/OleAut32/Wia_xp.cs @@ -1254,7 +1254,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/win32/api/wia_xp/nf-wia_xp-ienumwia_dev_caps-next HRESULT Next( ULONG celt, // WIA_DEV_CAP *rgelt, ULONG *pceltFetched ); [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] WIA_DEV_CAP[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] WIA_DEV_CAP[] rgelt, out uint pceltFetched); /// /// The IEnumWIA_DEV_CAPS::Skip method skips the specified number of hardware device capabilities during an enumeration @@ -1329,7 +1329,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/win32/api/wia_xp/nf-wia_xp-ienumwia_dev_info-next HRESULT Next( ULONG celt, // IWiaPropertyStorage **rgelt, ULONG *pceltFetched ); [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 2)] IWiaPropertyStorage[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 0)] IWiaPropertyStorage[] rgelt, out uint pceltFetched); /// /// The IEnumWIA_DEV_INFO::Skip method skips the specified number of hardware devices during an enumeration of available devices. @@ -1397,7 +1397,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/win32/api/wia_xp/nf-wia_xp-ienumwia_format_info-next HRESULT Next( ULONG celt, // WIA_FORMAT_INFO *rgelt, ULONG *pceltFetched ); [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] WIA_FORMAT_INFO[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] WIA_FORMAT_INFO[] rgelt, out uint pceltFetched); /// The IEnumWIA_FORMAT_INFO::Skip method skips the specified number of structures in the enumeration. /// Specifies the number of structures to skip. @@ -1488,7 +1488,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/win32/api/wia_xp/nf-wia_xp-ienumwiaitem-next HRESULT Next( ULONG celt, IWiaItem // **ppIWiaItem, ULONG *pceltFetched ); [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] IWiaItem[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IWiaItem[] rgelt, out uint pceltFetched); /// /// The IEnumWiaItem::Skip method skips the specified number of items during an enumeration of available IWiaItem objects. diff --git a/PInvoke/SearchApi/SearchApi.cs b/PInvoke/SearchApi/SearchApi.cs index 5bb765bd..6f7cdd4f 100644 --- a/PInvoke/SearchApi/SearchApi.cs +++ b/PInvoke/SearchApi/SearchApi.cs @@ -568,7 +568,7 @@ namespace Vanara.PInvoke // ISearchRoot **rgelt, ULONG *pceltFetched ); [PInvokeData("searchapi.h")] [PreserveSig] - HRESULT Next([In] uint celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISearchRoot[] rgelt, out uint pceltFetched); + HRESULT Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 0)] ISearchRoot[] rgelt, out uint pceltFetched); /// Skips the specified number of elements. /// @@ -648,7 +648,7 @@ namespace Vanara.PInvoke // celt, ISearchScopeRule **pprgelt, ULONG *pceltFetched ); [PInvokeData("searchapi.h")] [PreserveSig] - HRESULT Next([In] uint celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISearchScopeRule[] pprgelt, ref uint pceltFetched); + HRESULT Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 0)] ISearchScopeRule[] pprgelt, ref uint pceltFetched); /// Skips the specified number of elements. /// diff --git a/PInvoke/Shell32/ShObjIdl.IAssocHandler.cs b/PInvoke/Shell32/ShObjIdl.IAssocHandler.cs index 8de4df6c..6a62dd49 100644 --- a/PInvoke/Shell32/ShObjIdl.IAssocHandler.cs +++ b/PInvoke/Shell32/ShObjIdl.IAssocHandler.cs @@ -285,7 +285,7 @@ namespace Vanara.PInvoke /// // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ienumassochandlers-next HRESULT Next( ULONG // celt, IAssocHandler **rgelt, ULONG *pceltFetched ); - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 2)] IAssocHandler[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 0)] IAssocHandler[] rgelt, out uint pceltFetched); } } } \ No newline at end of file diff --git a/PInvoke/Shell32/ShObjIdl.IEnumObjects.cs b/PInvoke/Shell32/ShObjIdl.IEnumObjects.cs index dd65ed4b..8601a8f7 100644 --- a/PInvoke/Shell32/ShObjIdl.IEnumObjects.cs +++ b/PInvoke/Shell32/ShObjIdl.IEnumObjects.cs @@ -42,7 +42,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ienumobjects-next HRESULT Next( ULONG celt, // REFIID riid, void **rgelt, ULONG *pceltFetched ); [PreserveSig] - HRESULT Next(uint celt, in Guid riid, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.IUnknown, SizeParamIndex = 3)] object[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, in Guid riid, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.IUnknown, SizeParamIndex = 0)] object[] rgelt, out uint pceltFetched); /// Skips a specified number of objects. /// diff --git a/PInvoke/Shell32/ShObjIdl.IExplorerCommand.cs b/PInvoke/Shell32/ShObjIdl.IExplorerCommand.cs index 3abc3370..dba94434 100644 --- a/PInvoke/Shell32/ShObjIdl.IExplorerCommand.cs +++ b/PInvoke/Shell32/ShObjIdl.IExplorerCommand.cs @@ -112,7 +112,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ienumexplorercommand-next HRESULT Next( // ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched ); [PreserveSig] - HRESULT Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 2)] IExplorerCommand[] pUICommand, out uint pceltFetched); + HRESULT Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 0)] IExplorerCommand[] pUICommand, out uint pceltFetched); /// Not currently implemented. /// diff --git a/PInvoke/Shell32/ShObjIdl.IShellFolder.cs b/PInvoke/Shell32/ShObjIdl.IShellFolder.cs index 72d232e7..9fc2c38c 100644 --- a/PInvoke/Shell32/ShObjIdl.IShellFolder.cs +++ b/PInvoke/Shell32/ShObjIdl.IShellFolder.cs @@ -443,7 +443,7 @@ namespace Vanara.PInvoke /// Returns S_OK if successful, or a COM-defined error code otherwise. [PreserveSig] HRESULT Next([In] uint celt, - [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] EXTRASEARCH[] rgelt, + [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] EXTRASEARCH[] rgelt, out uint pceltFetched); /// Skip a specified number of objects. diff --git a/PInvoke/Shell32/ShObjIdl.IShellItem.cs b/PInvoke/Shell32/ShObjIdl.IShellItem.cs index 0d2bb030..664fe837 100644 --- a/PInvoke/Shell32/ShObjIdl.IShellItem.cs +++ b/PInvoke/Shell32/ShObjIdl.IShellItem.cs @@ -387,7 +387,7 @@ namespace Vanara.PInvoke /// value will be 0 if there are no more items to retrieve. /// [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 2)] IShellItem[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface, SizeParamIndex = 0)] IShellItem[] rgelt, out uint pceltFetched); /// Skips the specified number of elements in the enumeration sequence. /// The number of IShellItem interfaces to skip. diff --git a/PInvoke/Shell32/ShObjIdl.IShellItemResources.cs b/PInvoke/Shell32/ShObjIdl.IShellItemResources.cs index 1cc0a8a7..a8499fb6 100644 --- a/PInvoke/Shell32/ShObjIdl.IShellItemResources.cs +++ b/PInvoke/Shell32/ShObjIdl.IShellItemResources.cs @@ -34,7 +34,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/fr-fr/windows/win32/api/shobjidl_core/nf-shobjidl_core-ienumresources-next HRESULT Next( ULONG // celt, SHELL_ITEM_RESOURCE *psir, ULONG *pceltFetched ); [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] SHELL_ITEM_RESOURCE[] psir, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] SHELL_ITEM_RESOURCE[] psir, out uint pceltFetched); /// Skips a specified number of resources. /// diff --git a/PInvoke/Shell32/ShObjIdl.cs b/PInvoke/Shell32/ShObjIdl.cs index 47903dcd..0c0c8e75 100644 --- a/PInvoke/Shell32/ShObjIdl.cs +++ b/PInvoke/Shell32/ShObjIdl.cs @@ -1047,7 +1047,7 @@ namespace Vanara.PInvoke /// value will be 0 if there are no more items to retrieve. /// [PreserveSig] - HRESULT Next(uint celt, [In, Out, MarshalAs(UnmanagedType.LPArray)] IntPtr[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] rgelt, out uint pceltFetched); /// Skips the specified number of elements in the enumeration sequence. /// The number of item identifiers to skip. @@ -1108,7 +1108,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ienumfullidlist-next HRESULT Next( ULONG // celt, PIDLIST_ABSOLUTE *rgelt, ULONG *pceltFetched ); [PreserveSig] - HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] IntPtr[] rgelt, out uint pceltFetched); + HRESULT Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] rgelt, out uint pceltFetched); /// Skips a specified number of IDLIST_ABSOLUTE items. ///