pull/423/head
David Hall 2023-07-07 15:01:10 -06:00
commit 3eb3091467
3 changed files with 36 additions and 22 deletions

View File

@ -108,7 +108,7 @@ namespace Vanara.PInvoke
/// The middle three members are reserved for future use.
/// </para>
/// </summary>
[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 8)]
[StructLayout(LayoutKind.Explicit)]
public sealed class PROPVARIANT : ICloneable, IComparable, IComparable<PROPVARIANT>, IDisposable, IEquatable<PROPVARIANT>
{
/// <summary>Value type tag.</summary>
@ -548,12 +548,12 @@ namespace Vanara.PInvoke
{
case VARTYPE.VT_VECTOR | VARTYPE.VT_BSTR:
foreach (var ptr in _blob.pBlobData.ToIEnum<IntPtr>((int)_blob.cbSize))
Marshal.FreeBSTR(Marshal.ReadIntPtr(ptr));
Marshal.FreeBSTR(ptr);
Marshal.FreeCoTaskMem(_blob.pBlobData);
break;
case VARTYPE.VT_VECTOR | VARTYPE.VT_LPSTR:
//foreach (var ptr in _blob.pBlobData.ToIEnum<IntPtr>((int)_blob.cbSize))
// Marshal.FreeCoTaskMem(Marshal.ReadIntPtr(ptr));
foreach (var ptr in _blob.pBlobData.ToIEnum<IntPtr>((int)_blob.cbSize))
Marshal.FreeCoTaskMem(ptr);
Marshal.FreeCoTaskMem(_blob.pBlobData);
break;
case VARTYPE.VT_VECTOR | VARTYPE.VT_I1:
@ -588,7 +588,7 @@ namespace Vanara.PInvoke
break;
}
vt = 0;
_ulong = 0;
_blob = new();
}
/// <summary>Copies the contents of one PROPVARIANT structure to another.</summary>
@ -1158,7 +1158,7 @@ namespace Vanara.PInvoke
/// </para>
/// <note>This structure is mostly used for arrays where the fixed structure size is critical for interop.</note>
/// </summary>
[StructLayout(LayoutKind.Sequential, Size = 16, Pack = 8)]
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct PROPVARIANT_IMMUTABLE
{
/// <summary>Value type tag.</summary>
@ -1173,18 +1173,18 @@ namespace Vanara.PInvoke
/// <summary>Reserved for future use.</summary>
private ushort wReserved3;
/// <summary>The value when a numeric value less than 8 bytes.</summary>
private ulong _ulong;
/// <summary>The BLOB when VT_BLOB</summary>
private BLOB _blob;
/// <summary>Performs an implicit conversion from <see cref="PROPVARIANT"/> to <see cref="PROPVARIANT_IMMUTABLE"/>.</summary>
/// <param name="pv">The PROPVARIANT instance.</param>
/// <returns>The resulting <see cref="PROPVARIANT_IMMUTABLE"/> instance from the conversion.</returns>
public static implicit operator PROPVARIANT_IMMUTABLE(PROPVARIANT pv) => new() { vt = pv.vt, wReserved1 = pv.wReserved1, wReserved2 = pv.wReserved2, wReserved3 = pv.wReserved3, _ulong = pv._ulong };
public static implicit operator PROPVARIANT_IMMUTABLE(PROPVARIANT pv) => new() { vt = pv.vt, wReserved1 = pv.wReserved1, wReserved2 = pv.wReserved2, wReserved3 = pv.wReserved3, _blob = pv._blob };
/// <summary>Performs an implicit conversion from <see cref="PROPVARIANT_IMMUTABLE"/> to <see cref="PROPVARIANT"/>.</summary>
/// <param name="pv">The PROPVARIANT_IMMUTABLE instance.</param>
/// <returns>The resulting <see cref="PROPVARIANT"/> instance from the conversion.</returns>
public static explicit operator PROPVARIANT(in PROPVARIANT_IMMUTABLE pv) => new() { vt = pv.vt, wReserved1 = pv.wReserved1, wReserved2 = pv.wReserved2, wReserved3 = pv.wReserved3, _ulong = pv._ulong };
public static explicit operator PROPVARIANT(in PROPVARIANT_IMMUTABLE pv) => new() { vt = pv.vt, wReserved1 = pv.wReserved1, wReserved2 = pv.wReserved2, wReserved3 = pv.wReserved3, _blob = pv._blob };
}
}
}

View File

@ -113,8 +113,8 @@ namespace Vanara.PInvoke
/// </para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/propidl/nn-propidl-ienumstatpropsetstg
[PInvokeData("propidl.h", MSDNShortId = "0000013B-0000-0000-C000-000000000046")]
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0e6d4d92-6738-11cf-9608-00aa00680db4")]
[PInvokeData("propidl.h", MSDNShortId = "8d5e658f-312c-4c91-8794-808b2e8dd182")]
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000013B-0000-0000-C000-000000000046")]
public interface IEnumSTATPROPSETSTG : Vanara.Collections.ICOMEnum<STATPROPSETSTG>
{
/// <summary>

View File

@ -1,5 +1,6 @@
using NUnit.Framework;
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using Vanara.InteropServices;
@ -67,32 +68,45 @@ namespace Vanara.PInvoke.Tests
[Test]
public void IPropSetStorageTest()
{
var propKey = PROPERTYKEY.System.Title;
var propSetKey = PROPERTYKEY.System.Title.Key;
// creates a new storage object using NTFS implementation
StgOpenStorageEx(TestCaseSources.LogFile, STGM.STGM_DIRECT | STGM.STGM_READWRITE | STGM.STGM_SHARE_EXCLUSIVE,
STGFMT.STGFMT_ANY, default, default, default, typeof(IPropertySetStorage).GUID, out var iptr).ThrowIfFailed();
using var istg = ComReleaserFactory.Create((IPropertySetStorage)iptr);
var prc = new PROPSPEC(propKey.Id);
var prcs = new[] { PROPERTYKEY.System.Title.Id, PROPERTYKEY.System.Author.Id, PROPERTYKEY.System.Comment.Id }.Select(propid => new PROPSPEC(propid)).ToArray();
var vals = prcs.Select((prc, idx) => "VALUE" + idx).ToArray();
// creates propertystorage
istg.Item.Create(propKey.Key, default, PROPSETFLAG.PROPSETFLAG_DEFAULT, STGM.STGM_CREATE | STGM.STGM_READWRITE | STGM.STGM_SHARE_EXCLUSIVE, out var ipse).ThrowIfFailed();
istg.Item.Create(propSetKey, default, PROPSETFLAG.PROPSETFLAG_DEFAULT, STGM.STGM_CREATE | STGM.STGM_READWRITE | STGM.STGM_SHARE_EXCLUSIVE, out var ipse).ThrowIfFailed();
using (var pipse = ComReleaserFactory.Create(ipse))
{
// write property
using var prv = new PROPVARIANT("VALUE", VarEnum.VT_LPWSTR);
ipse.WriteMultiple(new[] { prc }, new[] { prv }, PID_FIRST_USABLE).ThrowIfFailed();
// write properties
var prvs = vals.Select(val => new PROPVARIANT(val, VarEnum.VT_LPWSTR)).ToArray();
try
{
ipse.WriteMultiple(prcs, prvs, PID_FIRST_USABLE).ThrowIfFailed();
}
finally
{
foreach (var prv in prvs)
prv.Dispose();
}
}
//hr = ipse.Commit((uint)STGC.STGC_DEFAULT);
// read property
istg.Item.Open(propKey.Key, STGM.STGM_READ | STGM.STGM_SHARE_EXCLUSIVE, out ipse).ThrowIfFailed();
istg.Item.Open(propSetKey, STGM.STGM_READ | STGM.STGM_SHARE_EXCLUSIVE, out ipse).ThrowIfFailed();
using (var pipse = ComReleaserFactory.Create(ipse))
{
ipse.ReadMultiple(new[] { prc }, out var prvRead).ThrowIfFailed();
Assert.That(prvRead.Length, Is.EqualTo(1));
Assert.That(prvRead[0].Value, Is.EqualTo("VALUE"));
var prvs = new PROPVARIANT[0];
ipse.ReadMultiple(prcs, out var prvRead).ThrowIfFailed();
CollectionAssert.AreEqual(prvRead.Select(prv => prv.Value), vals);
foreach (var prv in prvs)
prv.Dispose();
}
}