Files
MeadeGeneric/Meade.net/ClassFactory.cs
T
ColinD 79a77d4e1d Merged in feature/LocalServer (pull request #5)
Feature/LocalServer

* Major refactor.  Switching over to a local server hub style driver allowing multiple programs to control the telescope at one time without the need for the POTH Hub

* Unified the setup dialog

* Implemented shared serial port, Both Telescope and Driver can connect at the same time.

* Ported the focuser implementation from the non server based version.

* Ported the telescope driver code.

* Fixed problem with # not being stripped from the returned string ends. Fixed issue with RA being returned as degress rather than hours.

* Telescope passes validation

* Added a lock around the focuser move.

* Reimplemented CommandBlind and CommandString

* Corrected version information

* Removed the Altitude support as there's a bug in the Autostar and Audiostar firmware
2019-05-17 14:21:26 +00:00

245 lines
8.2 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Collections;
namespace ASCOM.Meade.net
{
#region C# Definition of IClassFactory
//
// Provide a definition of theCOM IClassFactory interface.
//
[
ComImport, // This interface originated from COM.
ComVisible(false), // Must not be exposed to COM!!!
InterfaceType(ComInterfaceType.InterfaceIsIUnknown), // Indicate that this interface is not IDispatch-based.
Guid("00000001-0000-0000-C000-000000000046") // This GUID is the actual GUID of IClassFactory.
]
public interface IClassFactory
{
void CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject);
void LockServer(bool fLock);
}
#endregion
//
// Universal ClassFactory. Given a type as a parameter of the
// constructor, it implements IClassFactory for any interface
// that the class implements. Magic!!!
//
public class ClassFactory : IClassFactory
{
#region Access to ole32.dll functions for class factories
// Define two common GUID objects for public usage.
public static Guid IID_IUnknown = new Guid("{00000000-0000-0000-C000-000000000046}");
public static Guid IID_IDispatch = new Guid("{00020400-0000-0000-C000-000000000046}");
[Flags]
enum CLSCTX : uint
{
CLSCTX_INPROC_SERVER = 0x1,
CLSCTX_INPROC_HANDLER = 0x2,
CLSCTX_LOCAL_SERVER = 0x4,
CLSCTX_INPROC_SERVER16 = 0x8,
CLSCTX_REMOTE_SERVER = 0x10,
CLSCTX_INPROC_HANDLER16 = 0x20,
CLSCTX_RESERVED1 = 0x40,
CLSCTX_RESERVED2 = 0x80,
CLSCTX_RESERVED3 = 0x100,
CLSCTX_RESERVED4 = 0x200,
CLSCTX_NO_CODE_DOWNLOAD = 0x400,
CLSCTX_RESERVED5 = 0x800,
CLSCTX_NO_CUSTOM_MARSHAL = 0x1000,
CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000,
CLSCTX_NO_FAILURE_LOG = 0x4000,
CLSCTX_DISABLE_AAA = 0x8000,
CLSCTX_ENABLE_AAA = 0x10000,
CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000,
CLSCTX_INPROC = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
CLSCTX_ALL = CLSCTX_SERVER | CLSCTX_INPROC_HANDLER
}
[Flags]
enum REGCLS : uint
{
REGCLS_SINGLEUSE = 0,
REGCLS_MULTIPLEUSE = 1,
REGCLS_MULTI_SEPARATE = 2,
REGCLS_SUSPENDED = 4,
REGCLS_SURROGATE = 8
}
//
// CoRegisterClassObject() is used to register a Class Factory
// into COM's internal table of Class Factories.
//
[DllImport("ole32.dll")]
static extern int CoRegisterClassObject(
[In] ref Guid rclsid,
[MarshalAs(UnmanagedType.IUnknown)] object pUnk,
uint dwClsContext,
uint flags,
out uint lpdwRegister);
//
// Called by a COM EXE Server that can register multiple class objects
// to inform COM about all registered classes, and permits activation
// requests for those class objects.
// This function causes OLE to inform the SCM about all the registered
// classes, and begins letting activation requests into the server process.
//
[DllImport("ole32.dll")]
static extern int CoResumeClassObjects();
//
// Prevents any new activation requests from the SCM on all class objects
// registered within the process. Even though a process may call this API,
// the process still must call CoRevokeClassObject for each CLSID it has
// registered, in the apartment it registered in.
//
[DllImport("ole32.dll")]
static extern int CoSuspendClassObjects();
//
// CoRevokeClassObject() is used to unregister a Class Factory
// from COM's internal table of Class Factories.
//
[DllImport("ole32.dll")]
static extern int CoRevokeClassObject(uint dwRegister);
#endregion
#region Constructor and Private ClassFactory Data
protected Type m_ClassType;
protected Guid m_ClassId;
protected ArrayList m_InterfaceTypes;
protected uint m_ClassContext;
protected uint m_Flags;
protected UInt32 m_locked = 0;
protected uint m_Cookie;
protected string m_progid;
public ClassFactory(Type type)
{
if (type == null)
throw new ArgumentNullException("type");
m_ClassType = type;
//PWGS Get the ProgID from the MetaData
m_progid = Marshal.GenerateProgIdForType(type);
m_ClassId = Marshal.GenerateGuidForType(type); // Should be nailed down by [Guid(...)]
m_ClassContext = (uint)CLSCTX.CLSCTX_LOCAL_SERVER; // Default
m_Flags = (uint)REGCLS.REGCLS_MULTIPLEUSE | // Default
(uint)REGCLS.REGCLS_SUSPENDED;
m_InterfaceTypes = new ArrayList();
foreach (Type T in type.GetInterfaces()) // Save all of the implemented interfaces
m_InterfaceTypes.Add(T);
}
#endregion
#region Common ClassFactory Methods
public uint ClassContext
{
get { return m_ClassContext; }
set { m_ClassContext = value; }
}
public Guid ClassId
{
get { return m_ClassId; }
set { m_ClassId = value; }
}
public uint Flags
{
get { return m_Flags; }
set { m_Flags = value; }
}
public bool RegisterClassObject()
{
// Register the class factory
int i = CoRegisterClassObject
(
ref m_ClassId,
this,
m_ClassContext,
m_Flags,
out m_Cookie
);
return (i == 0);
}
public bool RevokeClassObject()
{
int i = CoRevokeClassObject(m_Cookie);
return (i == 0);
}
public static bool ResumeClassObjects()
{
int i = CoResumeClassObjects();
return (i == 0);
}
public static bool SuspendClassObjects()
{
int i = CoSuspendClassObjects();
return (i == 0);
}
#endregion
#region IClassFactory Implementations
//
// Implement creation of the type and interface.
//
void IClassFactory.CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject)
{
IntPtr nullPtr = new IntPtr(0);
ppvObject = nullPtr;
//
// Handle specific requests for implemented interfaces
//
foreach (Type iType in m_InterfaceTypes)
{
if (riid == Marshal.GenerateGuidForType(iType))
{
ppvObject = Marshal.GetComInterfaceForObject(Activator.CreateInstance(m_ClassType), iType);
return;
}
}
//
// Handle requests for IDispatch or IUnknown on the class
//
if (riid == IID_IDispatch)
{
ppvObject = Marshal.GetIDispatchForObject(Activator.CreateInstance(m_ClassType));
return;
}
else if (riid == IID_IUnknown)
{
ppvObject = Marshal.GetIUnknownForObject(Activator.CreateInstance(m_ClassType));
}
else
{
//
// Oops, some interface that the class doesn't implement
//
throw new COMException("No interface", unchecked((int)0x80004002));
}
}
void IClassFactory.LockServer(bool bLock)
{
if (bLock)
Server.CountLock();
else
Server.UncountLock();
// Always attempt to see if we need to shutdown this server application.
Server.ExitIf();
}
#endregion
}
}