|
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace EPocalipse.IFilter
{
[ComVisible(false)]
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000001-0000-0000-C000-000000000046")]
internal interface IClassFactory
{
void CreateInstance([MarshalAs(UnmanagedType.Interface)] object pUnkOuter, ref Guid refiid, [MarshalAs(UnmanagedType.Interface)] out object ppunk);
void LockServer(bool fLock);
}
/// <summary>
/// Utility class to get a Class Factory for a certain Class ID
/// by loading the dll that implements that class
/// </summary>
internal static class ComHelper
{
//DllGetClassObject fuction pointer signature
private delegate int DllGetClassObject(ref Guid ClassId, ref Guid InterfaceId, [Out, MarshalAs(UnmanagedType.Interface)] out object ppunk);
//Some win32 methods to load\unload dlls and get a function pointer
private class Win32NativeMethods
{
[DllImport("kernel32.dll", CharSet=CharSet.Ansi)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string lpFileName);
}
/// <summary>
/// Holds a list of dll handles and unloads the dlls
/// in the destructor
/// </summary>
private class DllList
{
private List<IntPtr> _dllList=new List<IntPtr>();
public void AddDllHandle(IntPtr dllHandle)
{
lock (_dllList)
{
_dllList.Add(dllHandle);
}
}
~DllList()
{
foreach (IntPtr dllHandle in _dllList)
{
try
{
Win32NativeMethods.FreeLibrary(dllHandle);
}
catch { };
}
}
}
static DllList _dllList=new DllList();
/// <summary>
/// Gets a class factory for a specific COM Class ID.
/// </summary>
/// <param name="dllName">The dll where the COM class is implemented</param>
/// <param name="filterPersistClass">The requested Class ID</param>
/// <returns>IClassFactory instance used to create instances of that class</returns>
internal static IClassFactory GetClassFactory(string dllName, string filterPersistClass)
{
//Load the class factory from the dll
IClassFactory classFactory=GetClassFactoryFromDll(dllName, filterPersistClass);
return classFactory;
}
private static IClassFactory GetClassFactoryFromDll(string dllName, string filterPersistClass)
{
//Load the dll
IntPtr dllHandle=Win32NativeMethods.LoadLibrary(dllName);
if (dllHandle==IntPtr.Zero)
return null;
//Keep a reference to the dll until the process\AppDomain dies
_dllList.AddDllHandle(dllHandle);
//Get a pointer to the DllGetClassObject function
IntPtr dllGetClassObjectPtr=Win32NativeMethods.GetProcAddress(dllHandle, "DllGetClassObject");
if (dllGetClassObjectPtr==IntPtr.Zero)
return null;
//Convert the function pointer to a .net delegate
DllGetClassObject dllGetClassObject=(DllGetClassObject)Marshal.GetDelegateForFunctionPointer(dllGetClassObjectPtr, typeof(DllGetClassObject));
//Call the DllGetClassObject to retreive a class factory for out Filter class
Guid filterPersistGUID=new Guid(filterPersistClass);
Guid IClassFactoryGUID=new Guid("00000001-0000-0000-C000-000000000046"); //IClassFactory class id
Object unk;
if (dllGetClassObject(ref filterPersistGUID, ref IClassFactoryGUID, out unk)!=0)
return null;
//Yippie! cast the returned object to IClassFactory
return (unk as IClassFactory);
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Mehdi first started programming when he was 8 on BBC+128k machine in 6512 processor language, after various hardware and software changes he eventually came across .net and c# which he has been using since v1.0.
He is formally educated as a system analyst Industrial engineer, but his programming passion continues.
* Mehdi is the 5th person to get 6 out of 7 Platinum's on Code-Project (13th Jan'12)
* Mehdi is the 3rd person to get 7 out of 7 Platinum's on Code-Project (26th Aug'16)