diff --git a/FileMagic.Native/Interop/MagicHelper.cs b/FileMagic.Native/Interop/MagicHelper.cs index 3f0a78c..b41fed3 100644 --- a/FileMagic.Native/Interop/MagicHelper.cs +++ b/FileMagic.Native/Interop/MagicHelper.cs @@ -125,13 +125,13 @@ internal static unsafe class MagicHelper /// file_public int magic_setparam(struct magic_set *ms, int param, const void *val) /// [DllImport("libmagic")] - public static extern int magic_setparam(MagicSet* ms, MagicParameters param, [In] IntPtr val); + public static extern int magic_setparam(MagicSet* ms, MagicParameters param, IntPtr val); /// /// file_public int magic_getparam(struct magic_set *ms, int param, void *val) /// [DllImport("libmagic")] - public static extern int magic_getparam(MagicSet* ms, MagicParameters param, [Out] IntPtr val); + public static extern int magic_getparam(MagicSet* ms, MagicParameters param, IntPtr val); internal static string GetError(MagicSet* handle) { diff --git a/FileMagic.Native/Interop/MagicParameters.cs b/FileMagic.Native/Interop/MagicParameters.cs index 750bc32..ce21fa4 100644 --- a/FileMagic.Native/Interop/MagicParameters.cs +++ b/FileMagic.Native/Interop/MagicParameters.cs @@ -24,6 +24,10 @@ namespace FileMagic.Native.Interop /// public enum MagicParameters { + /// + /// No parameters + /// + None = -1, /// /// #define MAGIC_PARAM_INDIR_MAX 0 /// diff --git a/FileMagic/MagicHandler.cs b/FileMagic/MagicHandler.cs index 6fabbb4..7849947 100644 --- a/FileMagic/MagicHandler.cs +++ b/FileMagic/MagicHandler.cs @@ -37,54 +37,68 @@ public static class MagicHandler /// Gets the file magic information /// /// Target file path - public static string GetMagicInfo(string filePath) => - GetMagicInfo(filePath, magicPathDefault); + /// Parameter to use + /// Parameter value to set to + public static string GetMagicInfo(string filePath, MagicParameters parameter = MagicParameters.None, int paramValue = 0) => + GetMagicInfo(filePath, magicPathDefault, parameter, paramValue); /// /// Gets the file magic information /// /// Target file path /// Path to the file magic database - public static string GetMagicInfo(string filePath, string magicPath) => - HandleMagic(filePath, !string.IsNullOrEmpty(magicPath) ? magicPath : magicPathDefault, MagicFlags.None); + /// Parameter to use + /// Parameter value to set to + public static string GetMagicInfo(string filePath, string magicPath, MagicParameters parameter = MagicParameters.None, int paramValue = 0) => + HandleMagic(filePath, !string.IsNullOrEmpty(magicPath) ? magicPath : magicPathDefault, MagicFlags.None, parameter, paramValue); /// /// Gets the file magic Mime information /// /// Target file path - public static string GetMagicMimeInfo(string filePath) => - GetMagicMimeInfo(filePath, magicPathDefault); + /// Parameter to use + /// Parameter value to set to + public static string GetMagicMimeInfo(string filePath, MagicParameters parameter = MagicParameters.None, int paramValue = 0) => + GetMagicMimeInfo(filePath, magicPathDefault, parameter, paramValue); /// /// Gets the file magic Mime information /// /// Target file path /// Path to the file magic database - public static string GetMagicMimeInfo(string filePath, string magicPath) => - HandleMagic(filePath, !string.IsNullOrEmpty(magicPath) ? magicPath : magicPathDefault, MagicFlags.Mime); + /// Parameter to use + /// Parameter value to set to + public static string GetMagicMimeInfo(string filePath, string magicPath, MagicParameters parameter = MagicParameters.None, int paramValue = 0) => + HandleMagic(filePath, !string.IsNullOrEmpty(magicPath) ? magicPath : magicPathDefault, MagicFlags.Mime, parameter, paramValue); /// /// Gets the file magic Mime type information /// /// Target file path - public static string GetMagicMimeType(string filePath) => - GetMagicMimeType(filePath, magicPathDefault); + /// Parameter to use + /// Parameter value to set to + public static string GetMagicMimeType(string filePath, MagicParameters parameter = MagicParameters.None, int paramValue = 0) => + GetMagicMimeType(filePath, magicPathDefault, parameter, paramValue); /// /// Gets the file magic Mime type information /// /// Target file path /// Path to the file magic database - public static string GetMagicMimeType(string filePath, string magicPath) => - HandleMagic(filePath, !string.IsNullOrEmpty(magicPath) ? magicPath : magicPathDefault, MagicFlags.MimeType); + /// Parameter to use + /// Parameter value to set to + public static string GetMagicMimeType(string filePath, string magicPath, MagicParameters parameter = MagicParameters.None, int paramValue = 0) => + HandleMagic(filePath, !string.IsNullOrEmpty(magicPath) ? magicPath : magicPathDefault, MagicFlags.MimeType, parameter, paramValue); /// /// Gets the file magic Mime type information /// /// Target file path /// Magic flags to customize the output and the behavior of the native library - public static string GetMagicCustomType(string filePath, MagicFlags flags) => - GetMagicCustomType(filePath, magicPathDefault, flags); + /// Parameter to use + /// Parameter value to set to + public static string GetMagicCustomType(string filePath, MagicFlags flags, MagicParameters parameter = MagicParameters.None, int paramValue = 0) => + GetMagicCustomType(filePath, magicPathDefault, flags, parameter, paramValue); /// /// Gets the file magic Mime type information @@ -92,10 +106,12 @@ public static string GetMagicCustomType(string filePath, MagicFlags flags) => /// Target file path /// Path to the file magic database /// Magic flags to customize the output and the behavior of the native library - public static string GetMagicCustomType(string filePath, string magicPath, MagicFlags flags) => - HandleMagic(filePath, !string.IsNullOrEmpty(magicPath) ? magicPath : magicPathDefault, flags); + /// Parameter to use + /// Parameter value to set to + public static string GetMagicCustomType(string filePath, string magicPath, MagicFlags flags, MagicParameters parameter = MagicParameters.None, int paramValue = 0) => + HandleMagic(filePath, !string.IsNullOrEmpty(magicPath) ? magicPath : magicPathDefault, flags, parameter, paramValue); - internal static string HandleMagic(string filePath, string magicPath, MagicFlags flags) + internal static string HandleMagic(string filePath, string magicPath, MagicFlags flags, MagicParameters parameter = MagicParameters.None, int paramValue = 0) { IntPtr magicStringHandle; @@ -111,6 +127,33 @@ internal static string HandleMagic(string filePath, string magicPath, MagicFlags // Open the magic handle var handle = MagicHelper.magic_open(flags); + // Check to see if we're going to set the parameter + if (parameter != MagicParameters.None) + { + var valuePtr = (IntPtr)paramValue; + var valueHandle = Marshal.AllocHGlobal(IntPtr.Size); + var valueHandleResult = Marshal.AllocHGlobal(IntPtr.Size); + Marshal.WriteIntPtr(valueHandle, valuePtr); + + // Set the parameter + int paramResult = MagicHelper.magic_setparam(handle, parameter, valueHandle); + if (paramResult != 0) + throw new MagicException($"Failed to set parameter {parameter} to {paramValue}: [{MagicHelper.GetErrorNumber(handle)}] {MagicHelper.GetError(handle)}"); + + // Validate the parameter + IntPtr result; + int paramGetResult = MagicHelper.magic_getparam(handle, parameter, valueHandleResult); + if (paramGetResult != 0) + throw new MagicException($"Failed to get parameter {parameter} value: [{MagicHelper.GetErrorNumber(handle)}] {MagicHelper.GetError(handle)}"); + result = Marshal.ReadIntPtr(valueHandleResult); + if (result != valuePtr) + throw new MagicException($"Failed to validate parameter {parameter} for value {paramValue} (got {result}): [{MagicHelper.GetErrorNumber(handle)}] {MagicHelper.GetError(handle)}"); + + // Free the addresses + Marshal.FreeHGlobal(valueHandle); + Marshal.FreeHGlobal(valueHandleResult); + } + // Use this handle to load the magic database int loadResult = MagicHelper.magic_load(handle, magicPath); if (loadResult != 0)