mirror of https://github.com/dahall/Vanara.git
Compare commits
13 Commits
c884e083c0
...
cd7f44dcb8
Author | SHA1 | Date |
---|---|---|
David Hall | cd7f44dcb8 | |
David Hall | 581a2980ba | |
David Hall | 880dd37c8e | |
David Hall | b2d9fa9a7b | |
David Hall | e17b7b67e8 | |
David Hall | d3793a106b | |
David Hall | 375657cf49 | |
David Hall | ab61a44669 | |
David Hall | d2bccd35f5 | |
David Hall | 5e567af638 | |
David Hall | b5ba4dce9c | |
David Hall | 8ea569f81c | |
David Hall | 45c0a6869c |
|
@ -1,9 +1,10 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>4.0.0-beta2</Version>
|
||||
<TargetFrameworks>net45;net48;net6.0;net7.0;net8.0-windows;netstandard2.0;netcoreapp3.1</TargetFrameworks>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||
<Version>4.0.0-beta2</Version>
|
||||
<PackageVersion>4.0.0-beta2</PackageVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Vanara.Extensions.Reflection;
|
||||
|
||||
namespace Vanara.PInvoke;
|
||||
|
||||
|
@ -780,7 +781,7 @@ public static partial class FwpUClnt
|
|||
/// <para>The GUID for a valid callout in the layer.</para>
|
||||
/// <para>Available when the action invokes a callout, that is, <c>type</c> contains <c>FWP_ACTION_FLAG_CALLOUT</c>.</para>
|
||||
/// </summary>
|
||||
public Guid calloutKey;
|
||||
public Guid calloutKey { get => filterType; set => filterType = value; }
|
||||
}
|
||||
|
||||
/// <summary>The <c>FWPM_CALLOUT_CHANGE0</c> structure specifies a change notification dispatched to subscribers.</summary>
|
||||
|
@ -1547,7 +1548,11 @@ public static partial class FwpUClnt
|
|||
/// documented in the WDK.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public ulong rawContext;
|
||||
public ulong rawContext
|
||||
{
|
||||
get => BitConverter.ToUInt64(providerContextKey.ToByteArray(), 0);
|
||||
set { var bytes = BitConverter.GetBytes(value); Array.Resize(ref bytes, 16); providerContextKey = new Guid(bytes); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
|
|
|
@ -1013,19 +1013,4 @@ public static partial class IMAPI
|
|||
/// </summary>
|
||||
IMAPI_READ_TRACK_ADDRESS_TYPE_SESSION,
|
||||
}
|
||||
|
||||
internal class SafeArrayMarshaler<T> : ICustomMarshaler
|
||||
{
|
||||
public static ICustomMarshaler GetInstance(string cookie) => new SafeArrayMarshaler<T>();
|
||||
|
||||
void ICustomMarshaler.CleanUpManagedData(object ManagedObj) { }
|
||||
void ICustomMarshaler.CleanUpNativeData(IntPtr pNativeData) => SafeArrayDestroy(pNativeData);
|
||||
int ICustomMarshaler.GetNativeDataSize() => -1;
|
||||
IntPtr ICustomMarshaler.MarshalManagedToNative(object ManagedObj) => throw new NotImplementedException();
|
||||
object ICustomMarshaler.MarshalNativeToManaged(IntPtr pNativeData)
|
||||
{
|
||||
var sa = new SafeSAFEARRAY(pNativeData, false);
|
||||
return sa.ToArray().Cast<T>().ToArray();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ using System.Collections;
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Runtime.InteropServices.CustomMarshalers;
|
||||
using static Vanara.PInvoke.OleAut32;
|
||||
|
||||
namespace Vanara.PInvoke;
|
||||
|
||||
|
@ -913,7 +914,7 @@ public static partial class IMAPI
|
|||
// https://docs.microsoft.com/en-us/windows/win32/api/imapi2/nf-imapi2-idiscformat2data-get_multisessioninterfaces HRESULT
|
||||
// get_MultisessionInterfaces( SAFEARRAY **value );
|
||||
[DispId(280)]
|
||||
IMultisession[] MultisessionInterfaces { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler<IMultisession>))] get; }
|
||||
object[] MultisessionInterfaces { get; }
|
||||
|
||||
/// <summary>Writes the data stream to the device.</summary>
|
||||
/// <param name="data">An <c>IStream</c> interface of the data stream to write.</param>
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Runtime.CompilerServices;
|
|||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Runtime.InteropServices.CustomMarshalers;
|
||||
using Vanara.Collections;
|
||||
using static Vanara.PInvoke.OleAut32;
|
||||
|
||||
namespace Vanara.PInvoke;
|
||||
|
||||
|
@ -1122,7 +1123,7 @@ public static partial class IMAPI
|
|||
// https://docs.microsoft.com/en-us/windows/win32/api/imapi2fs/nf-imapi2fs-ifilesystemimage-get_multisessioninterfaces HRESULT
|
||||
// get_MultisessionInterfaces( SAFEARRAY **pVal );
|
||||
[DispId(40)]
|
||||
IMultisession[] MultisessionInterfaces { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler<IMultisession>))] get; set; }
|
||||
object[] MultisessionInterfaces { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1639,7 +1640,8 @@ public static partial class IMAPI
|
|||
// https://docs.microsoft.com/en-us/windows/win32/api/imapi2fs/nf-imapi2fs-ifilesystemimage-get_multisessioninterfaces HRESULT
|
||||
// get_MultisessionInterfaces( SAFEARRAY **pVal );
|
||||
[DispId(40)]
|
||||
new IMultisession[] MultisessionInterfaces { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler<IMultisession>))] get; set; }
|
||||
//new IMultisession[] MultisessionInterfaces { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler<IMultisession>))] get; set; }
|
||||
new object[] MultisessionInterfaces { get; set; }
|
||||
|
||||
/// <summary>Retrieves the boot option array that will be utilized to generate the file system image.</summary>
|
||||
/// <value>
|
||||
|
@ -1652,7 +1654,8 @@ public static partial class IMAPI
|
|||
// https://docs.microsoft.com/en-us/windows/win32/api/imapi2fs/nf-imapi2fs-ifilesystemimage2-get_bootimageoptionsarray HRESULT
|
||||
// get_BootImageOptionsArray( SAFEARRAY **pVal );
|
||||
[DispId(60)]
|
||||
IBootOptions[] BootImageOptionsArray { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler<IBootOptions>))] get; set; }
|
||||
//IBootOptions[] BootImageOptionsArray { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler<IBootOptions>))] get; set; }
|
||||
object[] BootImageOptionsArray { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -2175,7 +2178,8 @@ public static partial class IMAPI
|
|||
// https://docs.microsoft.com/en-us/windows/win32/api/imapi2fs/nf-imapi2fs-ifilesystemimage-get_multisessioninterfaces HRESULT
|
||||
// get_MultisessionInterfaces( SAFEARRAY **pVal );
|
||||
[DispId(40)]
|
||||
new IMultisession[] MultisessionInterfaces { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler<IMultisession>))] get; set; }
|
||||
//new IMultisession[] MultisessionInterfaces { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler<IMultisession>))] get; set; }
|
||||
new object[] MultisessionInterfaces { get; set; }
|
||||
|
||||
/// <summary>Retrieves the boot option array that will be utilized to generate the file system image.</summary>
|
||||
/// <value>
|
||||
|
@ -2188,7 +2192,8 @@ public static partial class IMAPI
|
|||
// https://docs.microsoft.com/en-us/windows/win32/api/imapi2fs/nf-imapi2fs-ifilesystemimage2-get_bootimageoptionsarray HRESULT
|
||||
// get_BootImageOptionsArray( SAFEARRAY **pVal );
|
||||
[DispId(60)]
|
||||
new IBootOptions[] BootImageOptionsArray { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler<IBootOptions>))] get; set; }
|
||||
//new IBootOptions[] BootImageOptionsArray { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler<IBootOptions>))] get; set; }
|
||||
new object[] BootImageOptionsArray { get; set; }
|
||||
|
||||
/// <summary>Retrieves a property value that specifies if the UDF Metadata will be redundant in the file system image.</summary>
|
||||
/// <value>
|
||||
|
|
|
@ -422,28 +422,39 @@ public static partial class IpHlpApi
|
|||
// _MIB_UDPROW_OWNER_PID { DWORD dwLocalAddr; DWORD dwLocalPort; DWORD dwOwningPid; } MIB_UDPROW_OWNER_PID, *PMIB_UDPROW_OWNER_PID;
|
||||
[PInvokeData("udpmib.h", MSDNShortId = "b914b6eb-adf9-4a61-ae8f-05d3ff90ce90")]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct MIB_UDPROW_OWNER_PID
|
||||
public struct MIB_UDPROW_OWNER_PID : IComparable, IComparable<MIB_UDPROW_OWNER_PID>
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>The IPv4 address of the UDP endpoint on the local computer.</para>
|
||||
/// <para>
|
||||
/// A value of zero indicates a UDP listener willing to accept datagrams for any IP interface associated with the local computer.
|
||||
/// </para>
|
||||
/// <para>A value of zero indicates a UDP listener willing to accept datagrams for any IP interface associated with the local computer.</para>
|
||||
/// </summary>
|
||||
public IN_ADDR dwLocalAddr;
|
||||
|
||||
/// <summary>
|
||||
/// <para>The port number of the UDP endpoint on the local computer. This member is stored in network byte order.</para>
|
||||
/// </summary>
|
||||
/// <summary>The port number of the UDP endpoint on the local computer. This member is stored in network byte order.</summary>
|
||||
public uint dwLocalPort;
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// The PID of the process that issued the call to the bind function for the UDP endpoint. This member is set to 0 when the PID
|
||||
/// is unavailable.
|
||||
/// </para>
|
||||
/// The PID of the process that issued the call to the bind function for the UDP endpoint. This member is set to 0 when the PID is unavailable.
|
||||
/// </summary>
|
||||
public uint dwOwningPid;
|
||||
|
||||
/// <summary>The port number of the UDP endpoint on the local computer. This member is in host byte order.</summary>
|
||||
public ushort dwHostLocalPort { readonly get => ntohs((ushort)dwLocalPort); set => dwLocalPort = htons(value); }
|
||||
|
||||
/// <inheritdoc/>
|
||||
readonly int IComparable<MIB_UDPROW_OWNER_PID>.CompareTo(MIB_UDPROW_OWNER_PID p)
|
||||
{
|
||||
var cmp = ((IComparable<IN_ADDR>)dwLocalAddr).CompareTo(p.dwLocalAddr);
|
||||
if (cmp == 0)
|
||||
cmp = dwHostLocalPort.CompareTo(p.dwHostLocalPort);
|
||||
if (cmp == 0)
|
||||
cmp = dwOwningPid.CompareTo(p.dwOwningPid);
|
||||
return cmp;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
readonly int IComparable.CompareTo(object? obj) => obj is MIB_UDPROW_OWNER_PID i ? ((IComparable<MIB_UDPROW_OWNER_PID>)this).CompareTo(i) :
|
||||
(obj is null ? 1 : throw new ArgumentException("Invalid type for comparison.", nameof(obj)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -638,13 +638,19 @@ public static partial class Kernel32
|
|||
/// The ReadDirectoryChangesExW function should provide information that describes the changes within the specified directory,
|
||||
/// and return this information in the output buffer in the form of FILE_NOTIFY_INFORMATION structures.
|
||||
/// </summary>
|
||||
ReadDirectoryNotifyInformation,
|
||||
ReadDirectoryNotifyInformation = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The ReadDirectoryChangesExW function should provide extended information that describes the changes within the specified
|
||||
/// directory, and return this information in the output buffer in the form of FILE_NOTIFY_EXTENDED_INFORMATION structures.
|
||||
/// </summary>
|
||||
ReadDirectoryNotifyExtendedInformation,
|
||||
|
||||
/// <summary/>
|
||||
ReadDirectoryNotifyFullInformation,
|
||||
|
||||
/// <summary/>
|
||||
ReadDirectoryNotifyMaximumInformation
|
||||
}
|
||||
|
||||
/// <summary>Flags used by <see cref="FILE_REMOTE_PROTOCOL_INFO"/>.</summary>
|
||||
|
|
|
@ -1369,7 +1369,7 @@ public static partial class OleAut32
|
|||
// *psa, LONG *rgIndices, void *pv );
|
||||
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("oleauto.h", MSDNShortId = "7c837b4f-d319-4d98-934a-b585fe521bf8")]
|
||||
public static extern HRESULT SafeArrayPutElement(SafeSAFEARRAY psa, [MarshalAs(UnmanagedType.LPArray)] int[] rgIndices, [In, MarshalAs(UnmanagedType.Struct)] object pv);
|
||||
public static extern HRESULT SafeArrayPutElement(SafeSAFEARRAY psa, [MarshalAs(UnmanagedType.LPArray)] int[] rgIndices, [In, MarshalAs(UnmanagedType.Struct)] object? pv);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Stores the data element at the specified location in the array.</para>
|
||||
|
@ -1430,7 +1430,7 @@ public static partial class OleAut32
|
|||
// *psa, LONG *rgIndices, void *pv );
|
||||
[DllImport(Lib.OleAut32, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("oleauto.h", MSDNShortId = "7c837b4f-d319-4d98-934a-b585fe521bf8")]
|
||||
public static extern HRESULT SafeArrayPutElement(SafeSAFEARRAY psa, in int rgIndices, [In, MarshalAs(UnmanagedType.Struct)] object pv);
|
||||
public static extern HRESULT SafeArrayPutElement(SafeSAFEARRAY psa, in int rgIndices, [In, MarshalAs(UnmanagedType.Struct)] object? pv);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Stores the data element at the specified location in the array.</para>
|
||||
|
@ -1935,6 +1935,15 @@ public static partial class OleAut32
|
|||
/// </remarks>
|
||||
public VARTYPE VarType { get { SafeArrayGetVartype(this, out VARTYPE vt).ThrowIfFailed(); return vt; } }
|
||||
|
||||
/// <summary>Gets or sets the <see cref="object"/> at the specified index.</summary>
|
||||
/// <value>The <see cref="object"/>.</value>
|
||||
/// <param name="index">The index.</param>
|
||||
public object? this[int index]
|
||||
{
|
||||
get => GetValue(index);
|
||||
set => SetValue(value, index);
|
||||
}
|
||||
|
||||
/// <summary>Creates a SAFEARRAY from a .NET array.</summary>
|
||||
/// <param name="array">
|
||||
/// The array used to initialize the SAFEARRAY. This can be a single or multi-dimensional array, but cannot be a jagged array
|
||||
|
@ -1946,6 +1955,8 @@ public static partial class OleAut32
|
|||
{
|
||||
Type elemType = array.GetType().GetElementType()!;
|
||||
if (elemType.IsArray) throw new ArgumentException("Input array cannot be jagged.", nameof(array));
|
||||
if (elemType.IsCOMObject || elemType.IsImport && elemType.IsInterface) elementVarType = VARTYPE.VT_UNKNOWN;
|
||||
|
||||
// Create list of bounds in reverse
|
||||
SAFEARRAYBOUND[] bounds = new SAFEARRAYBOUND[array.Rank];
|
||||
for (int d = 0; d < bounds.Length; d++)
|
||||
|
@ -1953,7 +1964,7 @@ public static partial class OleAut32
|
|||
// Create safe array
|
||||
SafeSAFEARRAY sa = SafeArrayCreate(elementVarType, (uint)array.Rank, bounds);
|
||||
// Copy values
|
||||
if (elemType == typeof(object))
|
||||
if (elemType == typeof(object) || elementVarType == VARTYPE.VT_UNKNOWN)
|
||||
{
|
||||
switch (elementVarType)
|
||||
{
|
||||
|
@ -2175,7 +2186,7 @@ public static partial class OleAut32
|
|||
/// <param name="value">The new value for the specified element.</param>
|
||||
/// <param name="index">A 32-bit integer that represents the position of the Array element to set.</param>
|
||||
/// <exception cref="ArgumentException">To take objects, the SAFEARRAY must be for VARIANTS.</exception>
|
||||
public void SetValue(object value, int index)
|
||||
public void SetValue(object? value, int index)
|
||||
{
|
||||
if (VarType != VARTYPE.VT_VARIANT)
|
||||
throw new ArgumentException("To take objects, the SAFEARRAY must be for VARIANTS.");
|
||||
|
@ -2192,7 +2203,7 @@ public static partial class OleAut32
|
|||
/// <para>The order of the indices follows .NET <see cref="Array"/> order and not the backwards ordering imposed by <c>SafeArrayGetElement</c>.</para>
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentException">To take objects, the SAFEARRAY must be for VARIANTS.</exception>
|
||||
public void SetValue(object value, params int[] indices)
|
||||
public void SetValue(object? value, params int[] indices)
|
||||
{
|
||||
if (VarType != VARTYPE.VT_VARIANT)
|
||||
throw new ArgumentException("To take objects, the SAFEARRAY must be for VARIANTS.");
|
||||
|
@ -2244,14 +2255,7 @@ public static partial class OleAut32
|
|||
object eTypeVal = Activator.CreateInstance(eType)!;
|
||||
|
||||
// Get details and build Array instance
|
||||
int dims = Rank;
|
||||
SAFEARRAYBOUND[] bounds = new SAFEARRAYBOUND[dims];
|
||||
for (int i = 1; i <= dims; i++)
|
||||
{
|
||||
_ = SafeArrayGetLBound(this, (uint)i, out int lb);
|
||||
_ = SafeArrayGetUBound(this, (uint)i, out int ub);
|
||||
bounds[dims - i] = new SAFEARRAYBOUND(ub, lb);
|
||||
}
|
||||
SAFEARRAYBOUND[] bounds = GetBounds();
|
||||
Array ret = Array.CreateInstance(eType, Array.ConvertAll(bounds, b => (int)b.cElements), Array.ConvertAll(bounds, b => b.lLbound));
|
||||
|
||||
// Fill in values
|
||||
|
@ -2310,7 +2314,21 @@ public static partial class OleAut32
|
|||
public HRESULT Unlock() => SafeArrayUnlock(this);
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool InternalReleaseHandle() => SafeArrayDestroy(handle).Succeeded;
|
||||
protected override bool InternalReleaseHandle()
|
||||
{
|
||||
// Release all conversions from COM objects to pointers
|
||||
if (VarType is VARTYPE.VT_UNKNOWN or VARTYPE.VT_DISPATCH)
|
||||
{
|
||||
using SafeCoTaskMemHandle mem = new(SafeArrayGetElemsize(this));
|
||||
foreach ((int[] from, int[] _) in BuildIndexList(GetBounds()))
|
||||
{
|
||||
SafeArrayGetElement(this, from, mem).ThrowIfFailed();
|
||||
unsafe { VARIANT* pVar = (VARIANT*)mem.DangerousGetHandle(); Marshal.Release(pVar->byref); }
|
||||
}
|
||||
}
|
||||
// Release the array
|
||||
return SafeArrayDestroy(handle).Succeeded;
|
||||
}
|
||||
|
||||
private static IEnumerable<(int[] from, int[] to)> BuildIndexList(SAFEARRAYBOUND[] bounds)
|
||||
{
|
||||
|
@ -2336,7 +2354,59 @@ public static partial class OleAut32
|
|||
}
|
||||
}
|
||||
|
||||
private SAFEARRAYBOUND[] GetBounds()
|
||||
{
|
||||
int dims = Rank;
|
||||
SAFEARRAYBOUND[] bounds = new SAFEARRAYBOUND[dims];
|
||||
for (int i = 1; i <= dims; i++)
|
||||
{
|
||||
_ = SafeArrayGetLBound(this, (uint)i, out int lb);
|
||||
_ = SafeArrayGetUBound(this, (uint)i, out int ub);
|
||||
bounds[dims - i] = new SAFEARRAYBOUND(ub, lb);
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
IEnumerator IEnumerable.GetEnumerator() => ToArray().GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>Custom marshaler for SAFEARRAY types. This marshaler is used to marshal SAFEARRAY types to and from managed code.</summary>
|
||||
/// <typeparam name="T">The type of the array element.</typeparam>
|
||||
public class SafeArrayMarshaler<T> : ICustomMarshaler
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public static ICustomMarshaler GetInstance(string cookie) => new SafeArrayMarshaler<T>();
|
||||
|
||||
private static readonly Dictionary<object, SafeSAFEARRAY> store = [];
|
||||
|
||||
/// <inheritdoc/>
|
||||
void ICustomMarshaler.CleanUpManagedData(object ManagedObj) { if (ManagedObj is not null) store.Remove(ManagedObj); }
|
||||
|
||||
/// <inheritdoc/>
|
||||
void ICustomMarshaler.CleanUpNativeData(IntPtr pNativeData) => SafeArrayDestroy(pNativeData);
|
||||
|
||||
/// <inheritdoc/>
|
||||
int ICustomMarshaler.GetNativeDataSize() => -1;
|
||||
|
||||
/// <inheritdoc/>
|
||||
IntPtr ICustomMarshaler.MarshalManagedToNative(object ManagedObj)
|
||||
{
|
||||
if (ManagedObj is null) return IntPtr.Zero;
|
||||
if (ManagedObj.GetType().IsArray)
|
||||
{
|
||||
var sa = SafeSAFEARRAY.CreateFromArray((Array)ManagedObj, Ole32.PROPVARIANT.GetVarType(ManagedObj.GetType().GetElementType()));
|
||||
store.Add(ManagedObj, sa);
|
||||
return sa.DangerousGetHandle();
|
||||
}
|
||||
throw new ArgumentException("ManagedObj must be an array or null.", nameof(ManagedObj));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
object ICustomMarshaler.MarshalNativeToManaged(IntPtr pNativeData)
|
||||
{
|
||||
var sa = new SafeSAFEARRAY(pNativeData, false);
|
||||
return sa.ToArray().Cast<T>().ToArray();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -76,7 +76,7 @@ public static class OverlappedAsync
|
|||
if (asyncResult.IsCompleted) return;
|
||||
asyncResult.FreeOverlapped();
|
||||
if (code == 0x217) code = 0;
|
||||
asyncResult.Complete(true, (int)code);
|
||||
asyncResult.Complete(true, (int)code, bytes);
|
||||
}, userState);
|
||||
return ar;
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ public static class OverlappedAsync
|
|||
if (asyncResult.IsCompleted) return;
|
||||
asyncResult.FreeOverlapped();
|
||||
if (code == 0x217) code = 0;
|
||||
asyncResult.Complete(true, (int)code);
|
||||
asyncResult.Complete(true, (int)code, bytes);
|
||||
}, userState);
|
||||
return ar;
|
||||
}
|
||||
|
@ -157,6 +157,10 @@ public static class OverlappedAsync
|
|||
/// <summary>Gets a value that indicates whether the asynchronous operation completed synchronously.</summary>
|
||||
public bool CompletedSynchronously { get; internal set; } = true;
|
||||
|
||||
/// <summary>Gets the error code associated with an I/O operation completion on a thread pool.</summary>
|
||||
/// <value>The error code.</value>
|
||||
public int ErrorCode => errorCode;
|
||||
|
||||
/// <summary>Gets the handle to which this operation is bound.</summary>
|
||||
/// <value>The handle.</value>
|
||||
public HFILE Handle => handle;
|
||||
|
@ -172,13 +176,19 @@ public static class OverlappedAsync
|
|||
internal set => overlapped = value;
|
||||
}
|
||||
|
||||
/// <summary>Gets the number of bytes that are transferred with an I/O operation completion on a thread pool.</summary>
|
||||
/// <value>The number of bytes that are transferred.</value>
|
||||
public uint ProcessedBytes { get; internal set; }
|
||||
|
||||
/// <summary>Completes the specified synch.</summary>
|
||||
/// <param name="synch">The value for the <see cref="CompletedSynchronously"/> property.</param>
|
||||
/// <param name="error">The error code, if necessary.</param>
|
||||
internal void Complete(bool synch = false, int error = 0)
|
||||
/// <param name="bytes">The number of bytes that have been transferred, if supplied.</param>
|
||||
internal void Complete(bool synch = false, int error = 0, uint bytes = 0)
|
||||
{
|
||||
CompletedSynchronously = synch;
|
||||
errorCode = error;
|
||||
ProcessedBytes = bytes;
|
||||
if (IsCompleted) return;
|
||||
IsCompleted = true;
|
||||
lock (lockObj)
|
||||
|
|
|
@ -2493,13 +2493,10 @@ public static partial class User32
|
|||
/// </returns>
|
||||
public static IntPtr GetWindowLongAuto(HWND hWnd, WindowLongFlags nIndex)
|
||||
{
|
||||
IntPtr ret;
|
||||
if (IntPtr.Size == 4)
|
||||
ret = (IntPtr)GetWindowLong(hWnd, nIndex);
|
||||
else
|
||||
ret = GetWindowLongPtr(hWnd, nIndex);
|
||||
SetLastErrorEx(0, 0);
|
||||
IntPtr ret = IntPtr.Size == 4 ? (IntPtr)GetWindowLong(hWnd, nIndex) : GetWindowLongPtr(hWnd, nIndex);
|
||||
if (ret == IntPtr.Zero)
|
||||
throw new System.ComponentModel.Win32Exception();
|
||||
Win32Error.GetLastError().ThrowIfFailed();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Vanara.PInvoke.VssApi</id>
|
||||
<version>$version$</version>
|
||||
<version>4.0.0-beta2</version>
|
||||
<description>PInvoke API (methods, structures and constants) imported from Windows Volume Shadow Copy Service (VssApi.dll).</description>
|
||||
<copyright>Copyright © 2017-2023</copyright>
|
||||
<authors>David Hall</authors>
|
||||
|
@ -37,7 +37,6 @@
|
|||
</group>-->
|
||||
</dependencies>
|
||||
<releaseNotes></releaseNotes>
|
||||
<suppportedDlls>vssapi.dll</suppportedDlls>
|
||||
</metadata>
|
||||
<files>
|
||||
<!--<file src="bin\Release\net45\Win32\Vanara.PInvoke.VssApi*.???" target="lib\net45" />
|
||||
|
@ -49,7 +48,7 @@
|
|||
<file src="bin\Release\net48\x64\Vanara.PInvoke.VssApi*.???" target="runtimes\win10-x64\lib\net48" />-->
|
||||
<file src="bin\Release\net6.0\x64\Vanara.PInvoke.VssApi*.???" target="lib\net6.0" />
|
||||
<!--<file src="bin\Release\net6.0\Win32\Vanara.PInvoke.VssApi*.???" target="runtimes\win10-x86\lib\net6.0" />-->
|
||||
<file src="bin\Release\net6.0\x64\Vanara.PInvoke.VssApi*.???" target="runtimes\win10-x64\lib\net6.0" />
|
||||
<!--<file src="bin\Release\net6.0\x64\Vanara.PInvoke.VssApi*.???" target="runtimes\win10-x64\lib\net6.0" />-->
|
||||
<!--<file src="bin\Release\net7.0\Win32\Vanara.PInvoke.VssApi*.???" target="lib\net7.0" />
|
||||
<file src="bin\Release\net7.0\Win32\Vanara.PInvoke.VssApi*.???" target="runtimes\win10-x86\lib\net7.0" />
|
||||
<file src="bin\Release\net7.0\x64\Vanara.PInvoke.VssApi*.???" target="runtimes\win10-x64\lib\net7.0" />
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<UpdateFiles PackageSource="..\..\Package.targets" UpdateProjectFile="false">
|
||||
<File Path="AssemblyInfo.cpp">
|
||||
<Version>AssemblyInformationalVersionAttribute</Version>
|
||||
<Version type="sem">AssemblyVersionAttribute</Version>
|
||||
<Version type="v4">AssemblyVersionAttribute</Version>
|
||||
<Copyright>AssemblyCopyrightAttribute</Copyright>
|
||||
<Product>AssemblyProductAttribute</Product>
|
||||
</File>
|
||||
|
@ -206,6 +206,8 @@
|
|||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="pkgreadme.md" />
|
||||
<None Include="readme.md" />
|
||||
<None Include="Vanara.PInvoke.VssApi.nuspec" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
|
|
@ -7,14 +7,12 @@
|
|||
<AssemblyName>Vanara.PInvoke.VssApiMgd</AssemblyName>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<IsPackable>false</IsPackable>
|
||||
<!--<TargetFrameworks>net6.0</TargetFrameworks>-->
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Core\Vanara.Core.csproj" />
|
||||
<ProjectReference Include="..\Shared\Vanara.PInvoke.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
<Target Name="WipeObj" BeforeTargets="Clean;CoreClean">
|
||||
<!-- obj -->
|
||||
<!--<Target Name="WipeObj" BeforeTargets="Clean;CoreClean">
|
||||
<RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" ContinueOnError="true" />
|
||||
</Target>
|
||||
</Target>-->
|
||||
</Project>
|
|
@ -3080,7 +3080,7 @@ public static partial class WTSApi32
|
|||
public long LastInputTimeUTC;
|
||||
|
||||
/// <summary>The time of the last user input in the session.</summary>
|
||||
public DateTime LastInputTime => DateTime.FromFileTimeUtc(LogonTimeUTC);
|
||||
public DateTime LastInputTime => DateTime.FromFileTimeUtc(LastInputTimeUTC);
|
||||
|
||||
/// <summary>The time that the user logged on to the session.</summary>
|
||||
public long LogonTimeUTC;
|
||||
|
|
|
@ -1111,7 +1111,7 @@ public static partial class Ws2_32
|
|||
/// <summary>The IN_ADDR structure represents an IPv4 address.</summary>
|
||||
[PInvokeData("winsock2.h")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct IN_ADDR : IEquatable<IN_ADDR>
|
||||
public struct IN_ADDR : IEquatable<IN_ADDR>, IComparable, IComparable<IN_ADDR>
|
||||
{
|
||||
/// <summary>An IPv4 address formatted as a u_long.</summary>
|
||||
public uint S_addr;
|
||||
|
@ -1216,12 +1216,27 @@ public static partial class Ws2_32
|
|||
byte[] b = S_un_b;
|
||||
return $"{b[0]}.{b[1]}.{b[2]}.{b[3]}";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
readonly int IComparable.CompareTo(object? obj) => obj is IN_ADDR i ? S_addr.CompareTo(i.S_addr) : (obj is null ? 1 : throw new ArgumentException("Invalid type for comparison.", nameof(obj)));
|
||||
|
||||
/// <inheritdoc/>
|
||||
readonly int IComparable<IN_ADDR>.CompareTo(IN_ADDR other)
|
||||
{
|
||||
var b = S_un_b; var o = other.S_un_b;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (b[i] < o[i]) return -1;
|
||||
if (b[i] > o[i]) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The IN6_ADDR structure represents an IPv6 address.</summary>
|
||||
[PInvokeData("winsock2.h")]
|
||||
[StructLayout(LayoutKind.Sequential, Size = IN6_ADDR_SIZE)]
|
||||
public struct IN6_ADDR : IEquatable<IN6_ADDR>
|
||||
public struct IN6_ADDR : IEquatable<IN6_ADDR>, IComparable, IComparable<IN6_ADDR>
|
||||
{
|
||||
private const int IN6_ADDR_SIZE = 16;
|
||||
|
||||
|
@ -1229,7 +1244,7 @@ public static partial class Ws2_32
|
|||
private ulong upper;
|
||||
|
||||
/// <summary>The IPv6 standard loopback address (<c>IN6ADDR_LOOPBACK_INIT</c>).</summary>
|
||||
public static readonly IN6_ADDR Loopback = new(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 });
|
||||
public static readonly IN6_ADDR Loopback = new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
|
||||
|
||||
/// <summary>The IPv6 standard unspecified address (<c>IN6ADDR_ANY_INIT</c>).</summary>
|
||||
public static readonly IN6_ADDR Unspecified = new();
|
||||
|
@ -1464,6 +1479,21 @@ public static partial class Ws2_32
|
|||
/// <param name="other">The value to compare with this instance.</param>
|
||||
/// <returns><see langword="true"/> if the specified value is equal to this instance; otherwise, <see langword="false"/>.</returns>
|
||||
public readonly bool Equals(IN6_ADDR other) => lower == other.lower && upper == other.upper;
|
||||
|
||||
/// <inheritdoc/>
|
||||
readonly int IComparable.CompareTo(object? obj) => obj is IN6_ADDR i ? ((IComparable<IN6_ADDR>)this).CompareTo(i) : (obj is null ? 1 : throw new ArgumentException("Invalid type for comparison.", nameof(obj)));
|
||||
|
||||
/// <inheritdoc/>
|
||||
readonly int IComparable<IN6_ADDR>.CompareTo(IN6_ADDR other)
|
||||
{
|
||||
var b = bytes; var o = other.bytes;
|
||||
for (int i = 0; i < IN6_ADDR_SIZE; i++)
|
||||
{
|
||||
if (b[i] < o[i]) return -1;
|
||||
if (b[i] > o[i]) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -124,7 +124,7 @@ usp10.dll | [Vanara.PInvoke.Usp10](https://github.com/dahall/Vanara/blob/master/
|
|||
uxtheme.dll | [Vanara.PInvoke.UxTheme](https://github.com/dahall/Vanara/blob/master/PInvoke/UxTheme/readme.md) | ![Coverage](https://img.shields.io/badge/100%25-green.svg?style=flat-square) | [![Nuget](https://img.shields.io/nuget/v/Vanara.PInvoke.UxTheme?label=%20&logo=nuget&style=flat-square)![Nuget](https://img.shields.io/nuget/dt/Vanara.PInvoke.UxTheme?label=%20&style=flat-square)](https://www.nuget.org/packages/Vanara.PInvoke.UxTheme)
|
||||
Version.dll | [Vanara.PInvoke.Version](https://github.com/dahall/Vanara/blob/master/PInvoke/Version/readme.md) | ![Coverage](https://img.shields.io/badge/100%25-green.svg?style=flat-square) | [![Nuget](https://img.shields.io/nuget/v/Vanara.PInvoke.Version?label=%20&logo=nuget&style=flat-square)![Nuget](https://img.shields.io/nuget/dt/Vanara.PInvoke.Version?label=%20&style=flat-square)](https://www.nuget.org/packages/Vanara.PInvoke.Version)
|
||||
virtdisk.dll | [Vanara.PInvoke.VirtDisk](https://github.com/dahall/Vanara/blob/master/PInvoke/VirtDisk/readme.md) | ![Coverage](https://img.shields.io/badge/100%25-green.svg?style=flat-square) | [![Nuget](https://img.shields.io/nuget/v/Vanara.PInvoke.VirtDisk?label=%20&logo=nuget&style=flat-square)![Nuget](https://img.shields.io/nuget/dt/Vanara.PInvoke.VirtDisk?label=%20&style=flat-square)](https://www.nuget.org/packages/Vanara.PInvoke.VirtDisk)
|
||||
vssapi.dll | [Vanara.PInvoke.VssApiMgd](https://github.com/dahall/Vanara/blob/master/PInvoke/VssApiMgd/readme.md) | ![Coverage](https://img.shields.io/badge/100%25-green.svg?style=flat-square) | [![Nuget](https://img.shields.io/nuget/v/Vanara.PInvoke.VssApiMgd?label=%20&logo=nuget&style=flat-square)![Nuget](https://img.shields.io/nuget/dt/Vanara.PInvoke.VssApiMgd?label=%20&style=flat-square)](https://www.nuget.org/packages/Vanara.PInvoke.VssApiMgd)
|
||||
vssapi.dll | [Vanara.PInvoke.VssApi](https://github.com/dahall/Vanara/blob/master/PInvoke/VssApi/readme.md) | ![Coverage](https://img.shields.io/badge/100%25-green.svg?style=flat-square) | [![Nuget](https://img.shields.io/nuget/v/Vanara.PInvoke.VssApi?label=%20&logo=nuget&style=flat-square)![Nuget](https://img.shields.io/nuget/dt/Vanara.PInvoke.VssApi?label=%20&style=flat-square)](https://www.nuget.org/packages/Vanara.PInvoke.VssApi)
|
||||
WcmApi.dll | [Vanara.PInvoke.WcmApi](https://github.com/dahall/Vanara/blob/master/PInvoke/WcmApi/readme.md) | ![Coverage](https://img.shields.io/badge/100%25-green.svg?style=flat-square) | [![Nuget](https://img.shields.io/nuget/v/Vanara.PInvoke.WcmApi?label=%20&logo=nuget&style=flat-square)![Nuget](https://img.shields.io/nuget/dt/Vanara.PInvoke.WcmApi?label=%20&style=flat-square)](https://www.nuget.org/packages/Vanara.PInvoke.WcmApi)
|
||||
WcnApi.dll | [Vanara.PInvoke.WcnApi](https://github.com/dahall/Vanara/blob/master/PInvoke/WcnApi/readme.md) | ![Coverage](https://img.shields.io/badge/100%25-green.svg?style=flat-square) | [![Nuget](https://img.shields.io/nuget/v/Vanara.PInvoke.WcnApi?label=%20&logo=nuget&style=flat-square)![Nuget](https://img.shields.io/nuget/dt/Vanara.PInvoke.WcnApi?label=%20&style=flat-square)](https://www.nuget.org/packages/Vanara.PInvoke.WcnApi)
|
||||
websocket.dll | [Vanara.PInvoke.WebSocket](https://github.com/dahall/Vanara/blob/master/PInvoke/WebSocket/readme.md) | ![Coverage](https://img.shields.io/badge/100%25-green.svg?style=flat-square) | [![Nuget](https://img.shields.io/nuget/v/Vanara.PInvoke.WebSocket?label=%20&logo=nuget&style=flat-square)![Nuget](https://img.shields.io/nuget/dt/Vanara.PInvoke.WebSocket?label=%20&style=flat-square)](https://www.nuget.org/packages/Vanara.PInvoke.WebSocket)
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<AssemblyName>UnitTest.PInvoke.IMAPI</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\PInvoke\IMAPI\Vanara.PInvoke.IMAPI.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,55 @@
|
|||
using NUnit.Framework;
|
||||
using NUnit.Framework.Internal;
|
||||
using System.Linq;
|
||||
using static Vanara.PInvoke.IMAPI;
|
||||
|
||||
namespace Vanara.PInvoke.Tests;
|
||||
|
||||
[TestFixture]
|
||||
public class IMAPITests
|
||||
{
|
||||
[OneTimeSetUp]
|
||||
public void _Setup()
|
||||
{
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void _TearDown()
|
||||
{
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RecorderTest()
|
||||
{
|
||||
IDiscMaster2 discMaster = new();
|
||||
Assert.True(discMaster.IsSupportedEnvironment, "There are no media sources on which to test.");
|
||||
|
||||
IDiscRecorder2 discRecorder = new();
|
||||
discRecorder.InitializeDiscRecorder(discMaster[0]);
|
||||
discRecorder.SupportedProfiles.WriteValues();
|
||||
|
||||
// Get the media type in the recorder
|
||||
IDiscFormat2Data iDiscFormat2Data = new();
|
||||
Assert.True(iDiscFormat2Data.IsCurrentMediaSupported(discRecorder));
|
||||
iDiscFormat2Data.Recorder = discRecorder;
|
||||
IMAPI_MEDIA_PHYSICAL_TYPE mediaType = iDiscFormat2Data.CurrentPhysicalMediaType;
|
||||
TestContext.WriteLine($"Media Type : {mediaType.GetDescription()}");
|
||||
iDiscFormat2Data.SupportedWriteSpeedDescriptors.WriteValues();
|
||||
|
||||
// Create a file system and select media type
|
||||
IFileSystemImage iFileSystemImage = new();
|
||||
iFileSystemImage.ChooseImageDefaultsForMediaType(mediaType);
|
||||
|
||||
// If there are other recored sessions on the disc, import them into the file system image
|
||||
if (!iDiscFormat2Data.MediaHeuristicallyBlank)
|
||||
{
|
||||
iFileSystemImage.MultisessionInterfaces = iDiscFormat2Data.MultisessionInterfaces;
|
||||
iFileSystemImage.ImportFileSystem();
|
||||
}
|
||||
|
||||
// Get the total size of the file system image
|
||||
int fileMediaBlocks = iFileSystemImage.FreeMediaBlocks;
|
||||
int totalDiskSize = 2048 * fileMediaBlocks;
|
||||
TestContext.WriteLine($"Total Disk Size: {totalDiskSize}");
|
||||
}
|
||||
}
|
|
@ -280,7 +280,7 @@ public partial class IpHlpApiTests
|
|||
Assert.That(t5.dwNumEntries, Is.GreaterThan(0));
|
||||
MIB_UDPTABLE_OWNER_PID t10 = GetExtendedUdpTable<MIB_UDPTABLE_OWNER_PID>(UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
|
||||
Assert.That(t10.dwNumEntries, Is.GreaterThan(0));
|
||||
TestContext.WriteLine("UDP PID: " + string.Join(",", t10.Select(t => t.dwOwningPid)));
|
||||
TestContext.WriteLine("UDP PID:\n" + string.Join("\n", t10.OrderBy(t => t).Select(t => $"{t.dwLocalAddr}:{t.dwHostLocalPort}\t{t.dwOwningPid}")));
|
||||
MIB_UDP6TABLE_OWNER_PID t11 = GetExtendedUdpTable<MIB_UDP6TABLE_OWNER_PID>(UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID, ADDRESS_FAMILY.AF_INET6);
|
||||
Assert.That(t11.dwNumEntries, Is.GreaterThan(0));
|
||||
TestContext.WriteLine("UDP6 PID: " + string.Join(",", t11.Select(t => t.dwOwningPid)));
|
||||
|
|
20
Vanara.sln
20
Vanara.sln
|
@ -431,6 +431,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Windows.Shell.Common", "Uni
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSocket", "UnitTests\PInvoke\WebSocket\WebSocket.csproj", "{AEA2913A-5E67-4C33-823F-CE06295DB35A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IMAPI", "UnitTests\PInvoke\IMAPI\IMAPI.csproj", "{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -3771,6 +3773,23 @@ Global
|
|||
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Release|x64.Build.0 = Release|x64
|
||||
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Release|x86.ActiveCfg = Release|x86
|
||||
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Release|x86.Build.0 = Release|x86
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.Debug|x64.Build.0 = Debug|x64
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.Debug|x86.Build.0 = Debug|x86
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.DebugNoTests|Any CPU.ActiveCfg = DebugNoTests|Any CPU
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.DebugNoTests|Any CPU.Build.0 = DebugNoTests|Any CPU
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.DebugNoTests|x64.ActiveCfg = DebugNoTests|x64
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.DebugNoTests|x64.Build.0 = DebugNoTests|x64
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.DebugNoTests|x86.ActiveCfg = DebugNoTests|x86
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.DebugNoTests|x86.Build.0 = DebugNoTests|x86
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.Release|x64.ActiveCfg = Release|x64
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.Release|x64.Build.0 = Release|x64
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.Release|x86.ActiveCfg = Release|x86
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -3964,6 +3983,7 @@ Global
|
|||
{7729B4B9-4837-49D5-91CC-5BB66E23A376} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90}
|
||||
{2727B06D-1E73-4108-AFDE-39C1A6F99806} = {3EC6B40D-71D3-4E59-A0E0-544EC605FE11}
|
||||
{AEA2913A-5E67-4C33-823F-CE06295DB35A} = {385CAD2D-0A5E-4F80-927B-D5499D126B90}
|
||||
{55E8ADA4-D27A-42B9-8BFD-8313B2DEF6DB} = {385CAD2D-0A5E-4F80-927B-D5499D126B90}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {543FAC75-2AF1-4EF1-9609-B242B63FEED4}
|
||||
|
|
Loading…
Reference in New Issue