Fixed bug with CoTaskMemStringMarshaler being used for return values and is never called. Added marshaler to places where appropriate.

pull/10/head
David Hall 2018-01-15 09:41:05 -07:00
parent e617c912a3
commit e6910dc9a9
9 changed files with 48 additions and 63 deletions

View File

@ -387,14 +387,26 @@ namespace Vanara.PInvoke
PDCOT_NUMBER = 5
}
/// <summary>Gets an instance of a property description interface for a property specified by a PROPERTYKEY structure.</summary>
/// <param name="propkey">Reference to a PROPERTYKEY.</param>
/// <param name="riid">Reference to the interface ID of the requested interface.</param>
/// <param name="ppv">
/// When this function returns, contains the interface pointer requested in riid. This is typically IPropertyDescription, IPropertyDescriptionAliasInfo,
/// or IPropertyDescriptionSearchInfo.
/// </param>
/// <returns></returns>
[DllImport(Lib.PropSys, ExactSpelling = true)]
[PInvokeData("Propsys.h", MSDNShortId = "bb776503")]
public static extern HRESULT PSGetPropertyDescription(ref PROPERTYKEY propkey, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppv);
/// <summary>
/// Retrieves the property's canonical name given its PROPERTYKEY.
/// </summary>
/// <param name="propkey">A pointer to a PROPERTYKEY structure containing the property's identifiers.</param>
/// <param name="ppszCanonicalName">The address of a pointer to a buffer that receives the property name as a null-terminated Unicode string. It is the responsibility of the caller to release this string through a call to CoTaskMemFree once it is no longer needed.</param>
/// <param name="ppszCanonicalName">The address of a pointer to a buffer that receives the property name as a null-terminated Unicode string.</param>
[DllImport(Lib.PropSys, ExactSpelling = true)]
[PInvokeData("Propsys.h", MSDNShortId = "bb776502")]
public static extern HRESULT PSGetNameFromPropertyKey(ref PROPERTYKEY propkey, out SafeCoTaskMemString ppszCanonicalName);
public static extern HRESULT PSGetNameFromPropertyKey(ref PROPERTYKEY propkey, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))] out string ppszCanonicalName);
[ComImport, Guid("1F9FC1D0-C39B-4B26-817F-011967D3440E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[PInvokeData("Propsys.h", MSDNShortId = "bb761511")]
@ -414,19 +426,16 @@ namespace Vanara.PInvoke
PROPERTYKEY GetPropertyKey();
/// <summary>Gets the case-sensitive name by which a property is known to the system, regardless of its localized name.</summary>
/// <returns>When this method returns, contains the address of a pointer to the property's canonical name as a null-terminated Unicode string.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetCanonicalName();
SafeCoTaskMemString GetCanonicalName();
/// <summary>Gets the variant type of the property.</summary>
/// <returns>When this method returns, contains a pointer to a VARTYPE that indicates the property type. If the property is multi-valued, the value pointed to is a VT_VECTOR mask (VT_VECTOR ORed to the VARTYPE.</returns>
VARTYPE GetPropertyType();
/// <summary>Gets the display name of the property as it is shown in any UI.</summary>
/// <returns>Contains the address of a pointer to the property's name as a null-terminated Unicode string.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetDisplayName();
SafeCoTaskMemString GetDisplayName();
/// <summary>Gets the text used in edit controls hosted in various dialog boxes.</summary>
/// <returns>When this method returns, contains the address of a pointer to a null-terminated Unicode buffer that holds the invitation text.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetEditInvitation();
SafeCoTaskMemString GetEditInvitation();
/// <summary>Gets a set of flags that describe the uses and capabilities of the property.</summary>
/// <param name="mask">A mask that specifies which type flags to retrieve. A combination of values found in the PROPDESC_TYPE_FLAGS constants. To retrieve all type flags, pass PDTF_MASK_ALL</param>
/// <returns>When this method returns, contains a pointer to a value that consists of bitwise PROPDESC_TYPE_FLAGS values.</returns>
@ -461,8 +470,7 @@ namespace Vanara.PInvoke
/// <summary>Gets the localized display string that describes the current sort order.</summary>
/// <param name="fDescending">TRUE if ppszDescription should reference the string "Z on top"; FALSE to reference the string "A on top".</param>
/// <returns>When this method returns, contains the address of a pointer to the sort description as a null-terminated Unicode string.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetSortDescriptionLabel([In, MarshalAs(UnmanagedType.Bool)] bool fDescending);
SafeCoTaskMemString GetSortDescriptionLabel([In, MarshalAs(UnmanagedType.Bool)] bool fDescending);
/// <summary>Gets a value that describes how the property values are displayed when multiple items are selected in the UI.</summary>
/// <returns>When this method returns, contains a pointer to a value that indicates the aggregation type.</returns>
PROPDESC_AGGREGATION_TYPE GetAggregationType();

View File

@ -422,7 +422,7 @@ namespace Vanara.PInvoke
/// <returns>If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.</returns>
[DllImport(Lib.PropSys, ExactSpelling = true)]
[PInvokeData("Propvarutil.h", MSDNShortId = "bb776560")]
public static extern HRESULT PropVariantToStringAlloc([In] PROPVARIANT propVar, out SafeCoTaskMemString ppszOut);
public static extern HRESULT PropVariantToStringAlloc([In] PROPVARIANT propVar, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))] out string ppszOut);
/// <summary>Extracts data from a <see cref="PROPVARIANT" /> structure into a newly allocated strings in a newly allocated vector.</summary>
/// <param name="propVar">Reference to the source <see cref="PROPVARIANT" /> structure.</param>

View File

@ -31,7 +31,7 @@ namespace Vanara.InteropServices
/// <param name="pNativeData">A pointer to the unmanaged data to be destroyed.</param>
public void CleanUpNativeData(IntPtr pNativeData)
{
StringHelper.FreeString(pNativeData, charSet);
Marshal.FreeCoTaskMem(pNativeData);
}
/// <summary>Returns the size of the native data to be marshaled.</summary>

View File

@ -267,8 +267,7 @@ namespace Vanara.PInvoke
/// <summary>Retrieves the text currently entered in the dialog's File name edit box.</summary>
/// <returns>The address of a pointer to a buffer that, when this method returns successfully, receives the text.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler), MarshalCookie = "Unicode")]
string GetFileName();
SafeCoTaskMemString GetFileName();
/// <summary>Sets the title of the dialog.</summary>
/// <param name="pszTitle">A pointer to a buffer that contains the title text.</param>
@ -491,8 +490,7 @@ namespace Vanara.PInvoke
/// <summary>Retrieves the text currently entered in the dialog's File name edit box.</summary>
/// <returns>The address of a pointer to a buffer that, when this method returns successfully, receives the text.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler), MarshalCookie = "Unicode")]
new string GetFileName();
new SafeCoTaskMemString GetFileName();
/// <summary>Sets the title of the dialog.</summary>
/// <param name="pszTitle">A pointer to a buffer that contains the title text.</param>
@ -754,8 +752,7 @@ namespace Vanara.PInvoke
/// <summary>Retrieves the text currently entered in the dialog's File name edit box.</summary>
/// <returns>The address of a pointer to a buffer that, when this method returns successfully, receives the text.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler), MarshalCookie = "Unicode")]
new string GetFileName();
new SafeCoTaskMemString GetFileName();
/// <summary>Sets the title of the dialog.</summary>
/// <param name="pszTitle">A pointer to a buffer that contains the title text.</param>

View File

@ -743,8 +743,7 @@ namespace Vanara.PInvoke
/// When this method returns, contains the address of a pointer to a null-terminated buffer that contains the path. The calling application is
/// responsible for calling CoTaskMemFree to free this resource when it is no longer needed.
/// </returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetPath([In] KNOWN_FOLDER_FLAG dwFlags);
SafeCoTaskMemString GetPath([In] KNOWN_FOLDER_FLAG dwFlags);
/// <summary>Assigns a new path to a known folder.</summary>
/// <param name="dwFlags">Either zero or the following value: KF_FLAG_DONT_UNEXPAND</param>
@ -886,8 +885,7 @@ namespace Vanara.PInvoke
/// When this method returns, contains the address of a pointer to a null-terminated Unicode string that contains an error message if one was
/// generated. This value can be NULL.
/// </returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string Redirect([In, MarshalAs(UnmanagedType.LPStruct)] Guid rfid, [In] IntPtr hwnd, [In] KF_REDIRECT_FLAGS flags,
SafeCoTaskMemString Redirect([In, MarshalAs(UnmanagedType.LPStruct)] Guid rfid, [In] IntPtr hwnd, [In] KF_REDIRECT_FLAGS flags,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszTargetPath, [In] uint cFolders, [In, MarshalAs(UnmanagedType.LPStruct)] Guid pExclusion);
}

View File

@ -136,8 +136,7 @@ namespace Vanara.PInvoke
/// <summary>Gets the default icon for the library.</summary>
/// <returns>A null-terminated Unicode string that describes the location of the default icon. The string is returned as ModuleFileName,ResourceIndex or ModuleFileName,-ResourceID.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler), MarshalCookie = "Unicode")]
string GetIcon();
SafeCoTaskMemString GetIcon();
/// <summary>Sets the default icon for the library.</summary>
/// <param name="icon">A null-terminated Unicode string that describes the location of the default icon. The string must be formatted as ModuleFileName,ResourceIndex or ModuleFileName,-ResourceID.</param>

View File

@ -1,6 +1,5 @@
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
@ -46,8 +45,8 @@ namespace Vanara.PInvoke
return null;
var pathBuilder = new StringBuilder(260);
try { SHGetFolderPathEx(knownFolder, 0, null, pathBuilder, (uint)pathBuilder.Capacity); }
catch { return null; }
if (SHGetFolderPathEx(knownFolder, 0, null, pathBuilder, (uint)pathBuilder.Capacity).Failed)
return null;
return pathBuilder.ToString();
}
@ -66,7 +65,7 @@ namespace Vanara.PInvoke
if (string.IsNullOrEmpty(path))
return null;
SHCreateItemFromParsingName(path, null, Marshal.GenerateGuidForType(typeof(IShellItem)), out object unk);
SHCreateItemFromParsingName(path, null, typeof(IShellItem).GUID, out object unk).ThrowIfFailed();
return (IShellItem)unk;
}
}

View File

@ -633,8 +633,7 @@ namespace Vanara.PInvoke
/// <summary>Retrieves a file type handler's explicit Application User Model ID (AppUserModelID), if one has been declared.</summary>
/// <returns></returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetAppID();
SafeCoTaskMemString GetAppID();
}
/// <summary>Exposes methods that provide access to the ProgID associated with an object.</summary>
@ -649,8 +648,7 @@ namespace Vanara.PInvoke
/// <summary>Retrieves the ProgID associated with an object.</summary>
/// <returns>A pointer to a string that, when this method returns successfully, contains the ProgID.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetProgID();
SafeCoTaskMemString GetProgID();
}
/// <summary>
@ -665,13 +663,11 @@ namespace Vanara.PInvoke
/// <param name="dwFlags">
/// Flags that direct the handling of the item from which you're retrieving the info tip text. This value is commonly zero (QITIPF_DEFAULT).
/// </param>
/// <returns>
/// The address of a Unicode string pointer that, when this method returns successfully, receives the tip string pointer. Applications that implement
/// <param name="ppwszTip">The address of a Unicode string pointer that, when this method returns successfully, receives the tip string pointer. Applications that implement
/// this method must allocate memory for ppwszTip by calling CoTaskMemAlloc. Calling applications must call CoTaskMemFree to free the memory when it
/// is no longer needed.
/// </returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetInfoTip(QITIP dwFlags);
/// </param>>
void GetInfoTip(QITIP dwFlags, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))] out string ppwszTip);
/// <summary>Gets the information flags for an item. This method is not currently used.</summary>
/// <returns>A pointer to a value that receives the flags for the item. If no flags are to be returned, this value should be set to zero.</returns>
@ -920,8 +916,7 @@ namespace Vanara.PInvoke
/// <summary>Gets the display name of the IShellItem object.</summary>
/// <param name="sigdnName">One of the SIGDN values that indicates how the name should look.</param>
/// <returns>A value that, when this function returns successfully, receives the address of a pointer to the retrieved display name.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetDisplayName(SIGDN sigdnName);
SafeCoTaskMemString GetDisplayName(SIGDN sigdnName);
/// <summary>Gets a requested set of attributes of the IShellItem object.</summary>
/// <param name="sfgaoMask">
@ -972,8 +967,7 @@ namespace Vanara.PInvoke
/// <summary>Gets the display name of the IShellItem object.</summary>
/// <param name="sigdnName">One of the SIGDN values that indicates how the name should look.</param>
/// <returns>A value that, when this function returns successfully, receives the address of a pointer to the retrieved display name.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
new string GetDisplayName(SIGDN sigdnName);
new SafeCoTaskMemString GetDisplayName(SIGDN sigdnName);
/// <summary>Gets a requested set of attributes of the IShellItem object.</summary>
/// <param name="sfgaoMask">
@ -1068,8 +1062,7 @@ namespace Vanara.PInvoke
/// <summary>Gets the string value of a specified property key.</summary>
/// <param name="key">A reference to a PROPERTYKEY structure.</param>
/// <returns>A pointer to a Unicode string value.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetString([In] ref PROPERTYKEY key);
SafeCoTaskMemString GetString([In] ref PROPERTYKEY key);
/// <summary>Gets the UInt32 value of specified property key.</summary>
/// <param name="key">A reference to a PROPERTYKEY structure.</param>
@ -1283,9 +1276,9 @@ namespace Vanara.PInvoke
/// terminating null character.
/// </param>
/// <returns>Returns a pointer to an ITEMIDLIST structure that corresponds to the path.</returns>
[DllImport(Lib.Shell32, EntryPoint = "ILCreateFromPath", SetLastError = false)]
[DllImport(Lib.Shell32, EntryPoint = "ILCreateFromPathW", SetLastError = true)]
[PInvokeData("Shobjidl.h", MSDNShortId = "dd378420")]
public static extern IntPtr IntILCreateFromPath(string pszPath);
public static extern IntPtr IntILCreateFromPath([MarshalAs(UnmanagedType.LPWStr)] string pszPath);
/// <summary>
/// Specifies a unique application-defined Application User Model ID (AppUserModelID) that identifies the current process to the taskbar. This identifier

View File

@ -560,8 +560,7 @@ namespace Vanara.PInvoke
/// A pointer to a null-terminated string that contains the retrieved trigger description. Note that this string must be release by a call to
/// CoTaskMemFree after the string is no longer needed.
/// </returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetTriggerString([In] ushort iTrigger);
SafeCoTaskMemString GetTriggerString([In] ushort iTrigger);
/// <summary>Retrieves the work item run times for a specified time period.</summary>
/// <param name="pstBegin">A pointer to a SYSTEMTIME structure that contains the starting time of the time period to check. This value is inclusive.</param>
@ -635,8 +634,7 @@ namespace Vanara.PInvoke
/// <summary>Retrieves the comment for the work item.</summary>
/// <returns>A pointer to a null-terminated string that contains the retrieved comment for the current work item.</returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetComment();
SafeCoTaskMemString GetComment();
/// <summary>Sets the name of the work item's creator.</summary>
/// <param name="Creator">A null-terminated string that contains the name of the work item's creator.</param>
@ -647,8 +645,7 @@ namespace Vanara.PInvoke
/// A pointer to a null-terminated string that contains the name of the creator of the current work item. The application that invokes GetCreator is
/// responsible for freeing this string using the CoTaskMemFree function.
/// </returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetCreator();
SafeCoTaskMemString GetCreator();
/// <summary>This method stores application-defined data associated with the work item.</summary>
/// <param name="cBytes">The number of bytes in the data buffer. The caller allocates and frees this memory.</param>
@ -718,8 +715,7 @@ namespace Vanara.PInvoke
/// A pointer to a null-terminated string that contains the account name for the current work item. The empty string, L"", is returned for the local
/// system account. After processing the account name, be sure to call CoTaskMemFree to free the string.
/// </returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetAccountInformation();
SafeCoTaskMemString GetAccountInformation();
/// <summary>This method assigns a specific application to the current task.</summary>
/// <param name="pwszApplicationName">
@ -733,8 +729,7 @@ namespace Vanara.PInvoke
/// A pointer to a null-terminated string that contains the name of the application the current task is associated with. After processing this name,
/// call CoTaskMemFree to free resources.
/// </returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetApplicationName();
SafeCoTaskMemString GetApplicationName();
/// <summary>This method sets the command-line parameters for the task.</summary>
/// <param name="pwszParameters">
@ -748,8 +743,7 @@ namespace Vanara.PInvoke
/// A pointer to a null-terminated string that contains the command-line parameters for the task. The method that invokes GetParameters is
/// responsible for freeing this string using the CoTaskMemFree function.
/// </returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetParameters();
SafeCoTaskMemString GetParameters();
/// <summary>This method sets the working directory for the task.</summary>
/// <param name="pwszWorkingDirectory">
@ -767,8 +761,7 @@ namespace Vanara.PInvoke
/// A pointer to a null-terminated string that contains the task's working directory. The application that invokes GetWorkingDirectory is responsible
/// for freeing this string using the CoTaskMemFree function.
/// </returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetWorkingDirectory();
SafeCoTaskMemString GetWorkingDirectory();
/// <summary>This method sets the priority for the task.</summary>
/// <param name="dwPriority">
@ -842,8 +835,7 @@ namespace Vanara.PInvoke
/// A pointer to a null-terminated string that contains the name of the target computer for the current task. This string is allocated by the
/// application that invokes GetTargetComputer, and must also be freed using CoTaskMemFree.
/// </returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetTargetComputer();
SafeCoTaskMemString GetTargetComputer();
/// <summary>The Enum method retrieves a pointer to an OLE enumerator object that enumerates the tasks in the current task folder.</summary>
/// <returns>A pointer to a pointer to an IEnumWorkItems interface. This interface contains the enumeration context of the current task(s).</returns>
@ -923,8 +915,7 @@ namespace Vanara.PInvoke
/// A pointer to a pointer to a null-terminated string that describes the current task trigger. The method that invokes GetTriggerString is
/// responsible for freeing this string using the CoTaskMemFree function.
/// </returns>
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CoTaskMemStringMarshaler))]
string GetTriggerString();
SafeCoTaskMemString GetTriggerString();
/// <summary>The SetTrigger method sets the trigger criteria for a task trigger.</summary>
/// <param name="Trigger">A pointer to a TASK_TRIGGER structure that contains the values that define the new task trigger.</param>