diff --git a/PInvoke/IMAPI/IMAPIv2.Enums.cs b/PInvoke/IMAPI/IMAPIv2.Enums.cs index 5152a70a..d719c236 100644 --- a/PInvoke/IMAPI/IMAPIv2.Enums.cs +++ b/PInvoke/IMAPI/IMAPIv2.Enums.cs @@ -1013,19 +1013,4 @@ public static partial class IMAPI /// IMAPI_READ_TRACK_ADDRESS_TYPE_SESSION, } - - internal class SafeArrayMarshaler : ICustomMarshaler - { - public static ICustomMarshaler GetInstance(string cookie) => new SafeArrayMarshaler(); - - 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().ToArray(); - } - } } \ No newline at end of file diff --git a/PInvoke/IMAPI/IMAPIv2.cs b/PInvoke/IMAPI/IMAPIv2.cs index 9c31814c..03d8f7e3 100644 --- a/PInvoke/IMAPI/IMAPIv2.cs +++ b/PInvoke/IMAPI/IMAPIv2.cs @@ -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))] get; } + object[] MultisessionInterfaces { get; } /// Writes the data stream to the device. /// An IStream interface of the data stream to write. diff --git a/PInvoke/IMAPI/IMAPIv2FS.cs b/PInvoke/IMAPI/IMAPIv2FS.cs index 30410fa9..905903bb 100644 --- a/PInvoke/IMAPI/IMAPIv2FS.cs +++ b/PInvoke/IMAPI/IMAPIv2FS.cs @@ -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))] get; set; } + object[] MultisessionInterfaces { get; set; } } /// @@ -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))] get; set; } + //new IMultisession[] MultisessionInterfaces { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler))] get; set; } + new object[] MultisessionInterfaces { get; set; } /// Retrieves the boot option array that will be utilized to generate the file system image. /// @@ -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))] get; set; } + //IBootOptions[] BootImageOptionsArray { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler))] get; set; } + object[] BootImageOptionsArray { get; set; } } /// @@ -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))] get; set; } + //new IMultisession[] MultisessionInterfaces { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler))] get; set; } + new object[] MultisessionInterfaces { get; set; } /// Retrieves the boot option array that will be utilized to generate the file system image. /// @@ -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))] get; set; } + //new IBootOptions[] BootImageOptionsArray { [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SafeArrayMarshaler))] get; set; } + new object[] BootImageOptionsArray { get; set; } /// Retrieves a property value that specifies if the UDF Metadata will be redundant in the file system image. /// diff --git a/UnitTests/PInvoke/IMAPI/IMAPI.csproj b/UnitTests/PInvoke/IMAPI/IMAPI.csproj new file mode 100644 index 00000000..91d6bb9c --- /dev/null +++ b/UnitTests/PInvoke/IMAPI/IMAPI.csproj @@ -0,0 +1,8 @@ + + + UnitTest.PInvoke.IMAPI + + + + + \ No newline at end of file diff --git a/UnitTests/PInvoke/IMAPI/IMAPITests.cs b/UnitTests/PInvoke/IMAPI/IMAPITests.cs new file mode 100644 index 00000000..2a522e0a --- /dev/null +++ b/UnitTests/PInvoke/IMAPI/IMAPITests.cs @@ -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}"); + } +} \ No newline at end of file diff --git a/Vanara.sln b/Vanara.sln index 47ab756c..3c48fefe 100644 --- a/Vanara.sln +++ b/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}