Skip to content

Commit

Permalink
Changes in the hasher and MediaInfo callbacks.
Browse files Browse the repository at this point in the history
They now fully support 64 and 32 bit environments, so all the JMM Server and dll, can be used by any OS. Also changed all compilation settings in JMM Server and other libraries to Any CPU, since there is no more CPU restrictions.

Currently, JMM Server expects to have 2 directories called x86 and x64, The build automatically copies the correct hasher.dll to the right directory, but. you have to manually copy the correct MediaInfo.dll to both directories.

x86
|-hasher.dll
|-mediainfo.dll

x64
|-hasher.dll
|-mediainfo.dll

Hasher was broken and was not used for years, it's fixed now, also the CRC function is fixed and working, i did update all algos (MD4, MD5, SHA1, CRC) to assembler but only for the x86 version. x64 version is only CRC32. Since i didn't find any AMD64 assembler implementation of MD4 (ED2K) and i'm to lazy to code it. Anyway the new 'C' versions are also optimized.
  • Loading branch information
maxpiva committed Nov 17, 2014
1 parent d552f7f commit 84b8906
Show file tree
Hide file tree
Showing 33 changed files with 2,620 additions and 2,475 deletions.
7 changes: 6 additions & 1 deletion JMMContracts/JMMContracts.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
Expand Down Expand Up @@ -187,6 +188,10 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
Expand Down
1 change: 1 addition & 0 deletions JMMFileHelper/Crc32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace JMMFileHelper
{
public class Crc32 : HashAlgorithm
{

public const uint DefaultSeed = 0xffffffff;

readonly static uint[] CrcTable = new uint[] {
Expand Down
99 changes: 57 additions & 42 deletions JMMFileHelper/Hasher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,58 @@ namespace JMMFileHelper
public class Hasher
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public delegate int OnHashProgress([MarshalAs(UnmanagedType.LPWStr)]string strFileName, int nProgressPct);
public delegate int OnHashProgress([MarshalAs(UnmanagedType.LPStr)]string strFileName, int nProgressPct);

[System.Flags]
internal enum LoadLibraryFlags : uint
{
DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008
}
[DllImport("kernel32.dll")]
internal static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool FreeLibrary(IntPtr hModule);
private static readonly Destructor Finalise = new Destructor(); //static Destructor hack

internal sealed class Destructor
{
public IntPtr ModuleHandle;

~Destructor()
{
if (ModuleHandle != IntPtr.Zero)
{
FreeLibrary(ModuleHandle);
ModuleHandle = IntPtr.Zero;
}
}
}

static Hasher()
{
string fullexepath = System.Reflection.Assembly.GetExecutingAssembly().Location;
FileInfo fi = new FileInfo(fullexepath);
fullexepath = Path.Combine(fi.Directory.FullName, Environment.Is64BitProcess ? "x64" : "x86", "hasher.dll");
try
{
Finalise.ModuleHandle = LoadLibraryEx(fullexepath, IntPtr.Zero, 0);
}
catch (Exception)
{
Finalise.ModuleHandle = IntPtr.Zero;
}
}

#region DLL functions
[DllImport("hasher.dll", EntryPoint = "CalculateHashes_AsyncIO", CallingConvention = CallingConvention.Cdecl)]
[DllImport("hasher.dll", EntryPoint = "CalculateHashes_AsyncIO", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern int CalculateHashes_callback_dll(
[MarshalAs(UnmanagedType.LPWStr)] string szFileName,
[MarshalAs(UnmanagedType.LPStr)] string szFileName,
[MarshalAs(UnmanagedType.LPArray)] byte[] hash,
[MarshalAs(UnmanagedType.FunctionPtr)] OnHashProgress lpHashProgressFunc,
[MarshalAs(UnmanagedType.Bool)] bool getCRC32,
Expand All @@ -37,10 +83,10 @@ protected static bool CalculateHashes_dll(string strFileName, ref byte[] hash, O
return (nResult == 0);
}

public static bool UseDll()
{
return File.Exists("hasher.dll");
}





public static string HashToString(byte[] hash, int start, int length)
{
Expand All @@ -64,28 +110,18 @@ public static Hashes CalculateHashes(string strPath, OnHashProgress onHashProgre

public static Hashes CalculateHashes(string strPath, OnHashProgress onHashProgress, bool getED2k, bool getCRC32, bool getMD5, bool getSHA1)
{
// the DLL is returning the wrong results for CRC's so don't use it
bool gotED2k = false;
bool gotMD5 = false;
bool gotSHA1 = false;

bool stillNeedInfo = false;
Hashes rhash = new Hashes();
if (UseDll())
if (Finalise.ModuleHandle != IntPtr.Zero)
{
byte[] hash = new byte[56];


if (CalculateHashes_dll(strPath, ref hash, onHashProgress, getCRC32, getMD5, getSHA1))
{
rhash.ed2k = HashToString(hash, 0, 16);
//if (getCRC32) rhash.crc32 = HashToString(hash, 16, 4);
if (getCRC32) rhash.crc32 = HashToString(hash, 16, 4);
if (getMD5) rhash.md5 = HashToString(hash, 20, 16);
if (getSHA1) rhash.sha1 = HashToString(hash, 36, 20);

gotED2k = getED2k;
gotMD5 = getMD5;
gotSHA1 = getSHA1;
}
else
{
Expand All @@ -94,30 +130,9 @@ public static Hashes CalculateHashes(string strPath, OnHashProgress onHashProgre
rhash.md5 = string.Empty;
rhash.sha1 = string.Empty;
}

return rhash;
}
else
stillNeedInfo = true;

if (gotED2k)
{
if (getCRC32) stillNeedInfo = true;
}

bool getED2kTemp = getED2k && !gotED2k;
bool getMD5Temp = getMD5 && !gotMD5;
bool getSHA1Temp = getSHA1 && !gotSHA1;

if (stillNeedInfo)
{
Hashes rhashTemp = CalculateHashes_here(strPath, onHashProgress, getED2kTemp, getCRC32, getMD5Temp, getSHA1Temp);
rhash.crc32 = rhashTemp.crc32;
if (string.IsNullOrEmpty(rhash.ed2k)) rhash.ed2k = rhashTemp.ed2k;
if (string.IsNullOrEmpty(rhash.md5)) rhash.md5 = rhashTemp.md5;
if (string.IsNullOrEmpty(rhash.sha1)) rhash.sha1 = rhashTemp.sha1;
}

return rhash;
return CalculateHashes_here(strPath, onHashProgress, getED2k, getCRC32, getMD5, getSHA1);
}

protected static Hashes CalculateHashes_here(string strPath, OnHashProgress onHashProgress, bool getED2k, bool getCRC32, bool getMD5, bool getSHA1)
Expand Down
9 changes: 5 additions & 4 deletions JMMFileHelper/JMMFileHelper.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,19 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
Expand Down Expand Up @@ -80,7 +81,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\JMMContracts\JMMContracts.csproj">
<Project>{D777636B-F927-4C7D-9D00-4A7858E75F3E}</Project>
<Project>{d777636b-f927-4c7d-9d00-4a7858e75f3e}</Project>
<Name>JMMContracts</Name>
</ProjectReference>
</ItemGroup>
Expand Down
54 changes: 48 additions & 6 deletions JMMFileHelper/PlexMediaInfo/MediaInfoDLL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

using System;
using System.IO;
using System.Runtime.InteropServices;

#pragma warning disable 1591 // Disable XML documentation warnings
Expand Down Expand Up @@ -65,7 +66,27 @@ public enum InfoFileOptions
public class MediaInfo
{
//Import of DLL functions. DO NOT USE until you know what you do (MediaInfo DLL do NOT use CoTaskMemAlloc to allocate memory)
[DllImport("MediaInfo.dll")]


[System.Flags]
internal enum LoadLibraryFlags : uint
{
DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008
}
[DllImport("kernel32.dll")]
internal static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool FreeLibrary(IntPtr hModule);



[DllImport("MediaInfo.dll")]
private static extern IntPtr MediaInfo_New();
[DllImport("MediaInfo.dll")]
private static extern void MediaInfo_Delete(IntPtr Handle);
Expand Down Expand Up @@ -112,15 +133,36 @@ public class MediaInfo
[DllImport("MediaInfo.dll")]
private static extern IntPtr MediaInfo_Count_Get(IntPtr Handle, IntPtr StreamKind, IntPtr StreamNumber);

private static System.IntPtr moduleHandle = IntPtr.Zero;


//MediaInfo class
public MediaInfo() {
Handle = MediaInfo_New();
if(Environment.OSVersion.ToString().IndexOf("Windows") == -1)
MustUseAnsi = true;
else
MustUseAnsi = false;
if (Environment.OSVersion.ToString().IndexOf("Windows") == -1)
{
if (moduleHandle == IntPtr.Zero)
{
string fullexepath = System.Reflection.Assembly.GetExecutingAssembly().Location;
FileInfo fi = new FileInfo(fullexepath);
fullexepath = Path.Combine(fi.Directory.FullName, Environment.Is64BitProcess ? "x64" : "x86", "MediaInfo.dll");
moduleHandle = LoadLibraryEx(fullexepath, IntPtr.Zero, 0);
}
MustUseAnsi = true;
}
else
MustUseAnsi = false;
}
~MediaInfo() { MediaInfo_Delete(Handle); }

~MediaInfo()
{
MediaInfo_Delete(Handle);
if (moduleHandle == IntPtr.Zero)
{
FreeLibrary(moduleHandle);
moduleHandle = IntPtr.Zero;
}
}
public int Open(String FileName) {
if(MustUseAnsi) {
IntPtr FileName_Ptr = Marshal.StringToHGlobalAnsi(FileName);
Expand Down
Loading

0 comments on commit 84b8906

Please sign in to comment.