Fixed #441 and added unit test for IMAPI.

nullableenabled
David Hall 2024-03-28 12:04:22 -06:00
parent d2bccd35f5
commit ab61a44669
6 changed files with 95 additions and 21 deletions

View File

@ -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();
}
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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}");
}
}

View File

@ -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}