MzCOM: avoid the ATL framework
Building MzCOM without ATL means that Visual Studio Express --- or other free compilers, in principle --- can build MzCOM. It also cleans up and simplifies the build. The non-ATL implementation is based on "Com in Plain C" by Jeff Glatt, and uses a lot of his code (with instructive comments intact).
This commit is contained in:
parent
165bae6c2c
commit
dfeba12997
704
racket/src/mzcom/com_glue.c
Normal file
704
racket/src/mzcom/com_glue.c
Normal file
|
@ -0,0 +1,704 @@
|
|||
/* Much of this code is from "COM in Plain C" by Jeff Gatt on Code
|
||||
Project. That code is licensed under the Code Project Open License
|
||||
(CPOL). */
|
||||
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
#include <activscp.h>
|
||||
#include <olectl.h>
|
||||
#include <stddef.h>
|
||||
#define FOR_GLUE
|
||||
#include "com_glue.h"
|
||||
|
||||
// A count of how many objects our DLL has created (by some
|
||||
// app calling our IClassFactory object's CreateInstance())
|
||||
// which have not yet been Release()'d by the app
|
||||
static DWORD OutstandingObjects;
|
||||
|
||||
// A count of how many apps have locked our DLL via calling our
|
||||
// IClassFactory object's LockServer()
|
||||
static DWORD LockCount;
|
||||
|
||||
// Where I store a pointer to my type library's TYPEINFO
|
||||
static ITypeInfo *MyTypeInfo;
|
||||
|
||||
// The MzObj object ////////////////////////////////////////////////////////////
|
||||
|
||||
// In our .H file, we use a macro which defines our MzObj struct
|
||||
// as so:
|
||||
//
|
||||
// typedef struct {
|
||||
// IMzObjVtbl *lpVtbl;
|
||||
// } MzObj;
|
||||
//
|
||||
// In other words, the .H file defines our MzObj to have nothing
|
||||
// but a pointer to its VTable. And of course, every COM object must
|
||||
// start with a pointer to its VTable.
|
||||
//
|
||||
// But we actually want to add some more members to our MzObj.
|
||||
// We just don't want any app to be able to know about, and directly
|
||||
// access, those members. So here we'll define a MyRealMzObj that
|
||||
// contains those extra members. The app doesn't know that we're
|
||||
// really allocating and giving it a MyRealMzObj object. We'll
|
||||
// lie and tell it we're giving a plain old MzObj. That's ok
|
||||
// because a MyRealMzObj starts with the same VTable pointer.
|
||||
//
|
||||
// We add a DWORD reference count so that this MzObj
|
||||
// can be allocated (which we do in our IClassFactory object's
|
||||
// CreateInstance()) and later freed. And, we have an extra
|
||||
// BSTR (pointer) string, which is used by some of the functions we'll
|
||||
// add to MzObj
|
||||
typedef struct {
|
||||
IMzObjVtbl *lpVtbl;
|
||||
DWORD count;
|
||||
void *obj;
|
||||
IConnectionPointContainer container;
|
||||
IConnectionPoint point;
|
||||
IMzObjEvents *evts;
|
||||
} MyRealMzObj;
|
||||
|
||||
// Here are MzObj's functions.
|
||||
//
|
||||
// Every COM object's interface must have the 3 functions QueryInterface(),
|
||||
// AddRef(), and Release().
|
||||
//
|
||||
// I also chose to add 2, extra functions to MzObj, which a program
|
||||
// will call with the names GetString and SetString.
|
||||
|
||||
// MzObj's QueryInterface()
|
||||
static HRESULT STDMETHODCALLTYPE QueryInterface(IMzObj *com_obj, REFIID vTableGuid, void **ppv)
|
||||
{
|
||||
// Because our IMzObj sources events, we must return an
|
||||
// IConnectionPointContainer sub-object if the app asks for one. Because we've
|
||||
// embedded our IConnectionPointContainer object inside of our MyRealIMzObj,
|
||||
// we can get that sub-object very easily using pointer arithmetic
|
||||
if (IsEqualIID(vTableGuid, &IID_IConnectionPointContainer))
|
||||
*ppv = ((unsigned char *)com_obj + offsetof(MyRealMzObj, container));
|
||||
else if (IsEqualIID(vTableGuid, &IID_IConnectionPoint))
|
||||
*ppv = ((unsigned char *)com_obj + offsetof(MyRealMzObj, point));
|
||||
|
||||
// Check if the GUID matches MzObj VTable's GUID. We gave the C variable name
|
||||
// IID_MzObj to our VTable GUID. We can use an OLE function called
|
||||
// IsEqualIID to do the comparison for us. Also, if the caller passed a
|
||||
// IUnknown GUID, then we'll likewise return the MzObj, since it can
|
||||
// masquerade as an IUnknown object too. Finally, if the called passed a
|
||||
// IDispatch GUID, then we'll return the MzObj, since it can masquerade
|
||||
// as an IDispatch too
|
||||
else if (!IsEqualIID(vTableGuid, &IID_IUnknown) && !IsEqualIID(vTableGuid, &IID_IMzObj) && !IsEqualIID(vTableGuid, &IID_IDispatch))
|
||||
{
|
||||
// We don't recognize the GUID passed to us. Let the caller know this,
|
||||
// by clearing his handle, and returning E_NOINTERFACE.
|
||||
*ppv = 0;
|
||||
return(E_NOINTERFACE);
|
||||
}
|
||||
else
|
||||
// Fill in the caller's handle
|
||||
*ppv = com_obj;
|
||||
|
||||
// Increment the count of callers who have an outstanding pointer to this object
|
||||
com_obj->lpVtbl->AddRef(com_obj);
|
||||
|
||||
return(NOERROR);
|
||||
}
|
||||
|
||||
// MzObj's AddRef()
|
||||
static ULONG STDMETHODCALLTYPE AddRef(IMzObj *com_obj)
|
||||
{
|
||||
// Increment MzObj's reference count, and return the updated value.
|
||||
// NOTE: We have to typecast to gain access to any data members. These
|
||||
// members are not defined in our .H file (so that an app can't directly
|
||||
// access them). Rather they are defined only above in our MyRealMzObj
|
||||
// struct. So typecast to that in order to access those data members
|
||||
return(++((MyRealMzObj *)com_obj)->count);
|
||||
}
|
||||
|
||||
// MzObj's Release()
|
||||
static ULONG STDMETHODCALLTYPE Release(IMzObj *com_obj)
|
||||
{
|
||||
// Decrement MzObj's reference count. If 0, then we can safely free
|
||||
// this MzObj now
|
||||
if (--((MyRealMzObj *)com_obj)->count == 0)
|
||||
{
|
||||
delete_mzobj(((MyRealMzObj *)com_obj)->obj);
|
||||
GlobalFree(com_obj);
|
||||
InterlockedDecrement(&OutstandingObjects);
|
||||
|
||||
if (com_can_unregister()) {
|
||||
/* Only allowed object is released... */
|
||||
PostMessage(NULL, WM_QUIT, 0, 0);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
return(((MyRealMzObj *)com_obj)->count);
|
||||
}
|
||||
|
||||
// ================== The standard IDispatch functions
|
||||
|
||||
// This is just a helper function for the IDispatch functions below
|
||||
static HRESULT loadMyTypeInfo(void)
|
||||
{
|
||||
register HRESULT hr;
|
||||
LPTYPELIB pTypeLib;
|
||||
|
||||
// Load our type library and get a ptr to its TYPELIB. Note: This does an
|
||||
// implicit pTypeLib->lpVtbl->AddRef(pTypeLib)
|
||||
if (!(hr = LoadRegTypeLib(&CLSID_TypeLib, 1, 0, 0, &pTypeLib)))
|
||||
{
|
||||
// Get Microsoft's generic ITypeInfo, giving it our loaded type library. We only
|
||||
// need one of these, and we'll store it in a global Tell Microsoft this is for
|
||||
// our MzObj's VTable, by passing that VTable's GUID
|
||||
if (!(hr = pTypeLib->lpVtbl->GetTypeInfoOfGuid(pTypeLib, &IID_IMzObj, &MyTypeInfo)))
|
||||
{
|
||||
// We no longer need the ptr to the TYPELIB now that we've given it
|
||||
// to Microsoft's generic ITypeInfo. Note: The generic ITypeInfo has done
|
||||
// a pTypeLib->lpVtbl->AddRef(pTypeLib), so this TYPELIB ain't going away
|
||||
// until the generic ITypeInfo does a pTypeLib->lpVtbl->Release too
|
||||
pTypeLib->lpVtbl->Release(pTypeLib);
|
||||
|
||||
// Since caller wants us to return our ITypeInfo pointer,
|
||||
// we need to increment its reference count. Caller is
|
||||
// expected to Release() it when done
|
||||
MyTypeInfo->lpVtbl->AddRef(MyTypeInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return(hr);
|
||||
}
|
||||
|
||||
// MzObj's GetTypeInfoCount()
|
||||
static ULONG STDMETHODCALLTYPE GetTypeInfoCount(IMzObj *com_obj, UINT *pCount)
|
||||
{
|
||||
*pCount = 1;
|
||||
return(S_OK);
|
||||
}
|
||||
|
||||
// MzObj's GetTypeInfo()
|
||||
static ULONG STDMETHODCALLTYPE GetTypeInfo(IMzObj *com_obj, UINT itinfo, LCID lcid, ITypeInfo **pTypeInfo)
|
||||
{
|
||||
register HRESULT hr;
|
||||
|
||||
// Assume an error
|
||||
*pTypeInfo = 0;
|
||||
|
||||
if (itinfo)
|
||||
hr = ResultFromScode(DISP_E_BADINDEX);
|
||||
|
||||
// If our ITypeInfo is already created, just increment its ref count. NOTE: We really should
|
||||
// store the LCID of the currently created TYPEINFO and compare it to what the caller wants.
|
||||
// If no match, unloaded the currently created TYPEINFO, and create the correct one. But since
|
||||
// we support only one language in our IDL file anyway, we'll ignore this
|
||||
else if (MyTypeInfo)
|
||||
{
|
||||
MyTypeInfo->lpVtbl->AddRef(MyTypeInfo);
|
||||
hr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load our type library and get Microsoft's generic ITypeInfo object. NOTE: We really
|
||||
// should pass the LCID to match, but since we support only one language in our IDL
|
||||
// file anyway, we'll ignore this
|
||||
hr = loadMyTypeInfo();
|
||||
}
|
||||
|
||||
if (!hr) *pTypeInfo = MyTypeInfo;
|
||||
|
||||
return(hr);
|
||||
}
|
||||
|
||||
// MzObj's GetIDsOfNames()
|
||||
static ULONG STDMETHODCALLTYPE GetIDsOfNames(IMzObj *com_obj, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgdispid)
|
||||
{
|
||||
if (!MyTypeInfo)
|
||||
{
|
||||
register HRESULT hr;
|
||||
|
||||
if ((hr = loadMyTypeInfo())) return(hr);
|
||||
}
|
||||
|
||||
// Let OLE32.DLL's DispGetIDsOfNames() do all the real work of using our type
|
||||
// library to look up the DISPID of the requested function in our object
|
||||
return(DispGetIDsOfNames(MyTypeInfo, rgszNames, cNames, rgdispid));
|
||||
}
|
||||
|
||||
// MzObj's Invoke()
|
||||
static ULONG STDMETHODCALLTYPE Invoke(IMzObj *com_obj, DISPID dispid, REFIID riid, LCID lcid, WORD wFlags,
|
||||
DISPPARAMS *params, VARIANT *result, EXCEPINFO *pexcepinfo,
|
||||
UINT *puArgErr)
|
||||
{
|
||||
// We implement only a "default" interface
|
||||
if (!IsEqualIID(riid, &IID_NULL))
|
||||
return(DISP_E_UNKNOWNINTERFACE);
|
||||
|
||||
// We need our type lib's TYPEINFO (to pass to DispInvoke)
|
||||
if (!MyTypeInfo)
|
||||
{
|
||||
register HRESULT hr;
|
||||
|
||||
if ((hr = loadMyTypeInfo())) return(hr);
|
||||
}
|
||||
|
||||
// Let OLE32.DLL's DispInvoke() do all the real work of calling the appropriate
|
||||
// function in our object, and massaging the passed args into the correct format
|
||||
return(DispInvoke(com_obj, MyTypeInfo, dispid, wFlags, params, result, pexcepinfo, puArgErr));
|
||||
}
|
||||
|
||||
// ================== The following are my own extra functions added to MzObj
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Eval(IMzObj *com_obj, BSTR str, BSTR *res)
|
||||
{
|
||||
if (!str) return(E_POINTER);
|
||||
|
||||
return mzobj_eval(((MyRealMzObj*)com_obj)->obj, str, res);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE About(IMzObj *com_obj)
|
||||
{
|
||||
return mzobj_about(((MyRealMzObj*)com_obj)->obj);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Reset(IMzObj *com_obj)
|
||||
{
|
||||
return mzobj_reset(((MyRealMzObj*)com_obj)->obj);
|
||||
}
|
||||
|
||||
// Here's MzObj's VTable. It never changes so we can declare it
|
||||
// static
|
||||
static const IMzObjVtbl IMzObj_Vtbl = {QueryInterface,
|
||||
AddRef,
|
||||
Release,
|
||||
GetTypeInfoCount,
|
||||
GetTypeInfo,
|
||||
GetIDsOfNames,
|
||||
Invoke,
|
||||
Eval,
|
||||
About,
|
||||
Reset};
|
||||
|
||||
|
||||
VOID Fire_SchemeError(IMzObj *com_obj, BSTR description)
|
||||
{
|
||||
if (((MyRealMzObj*)com_obj)->evts) {
|
||||
VARIANTARG pvars[1];
|
||||
DISPPARAMS disp = { pvars, NULL, 1, 0 };
|
||||
memset(pvars, 0, sizeof(pvars));
|
||||
pvars[0].vt = VT_BSTR;
|
||||
pvars[0].bstrVal = description;
|
||||
((MyRealMzObj*)com_obj)->evts->lpVtbl->Invoke(((MyRealMzObj*)com_obj)->evts, 0x1, &IID_NULL,
|
||||
LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Our IConnectionPointContainer sub-object (for IMzObj) ////////////////////////
|
||||
|
||||
static STDMETHODIMP QueryInterface_Connect(IConnectionPointContainer *com_obj, REFIID vTableGuid, void **ppv)
|
||||
{
|
||||
// Because this is a sub-object of our IMzObj (ie, MyRealMzObj) object,
|
||||
// we delegate to IMzObj's QueryInterface. And because we embedded the
|
||||
// IConnectionPointContainer directly inside of MyRealMzObj, all we need
|
||||
// is a little pointer arithmetic to get our IMzObj
|
||||
return(QueryInterface((IMzObj *)((char *)com_obj - offsetof(MyRealMzObj, container)), vTableGuid, ppv));
|
||||
}
|
||||
|
||||
static STDMETHODIMP_(ULONG) AddRef_Connect(IConnectionPointContainer *com_obj)
|
||||
{
|
||||
// Because we're a sub-object of IMzObj, delegate to its AddRef()
|
||||
// in order to increment IMzObj's reference count
|
||||
return(AddRef((IMzObj *)((char *)com_obj - offsetof(MyRealMzObj, container))));
|
||||
}
|
||||
|
||||
static STDMETHODIMP_(ULONG) Release_Connect(IConnectionPointContainer *com_obj)
|
||||
{
|
||||
// Because we're a sub-object of IMzObj, delegate to its Release()
|
||||
// in order to decrement IMzObj's reference count
|
||||
return(Release((IMzObj *)((char *)com_obj - offsetof(MyRealMzObj, container))));
|
||||
}
|
||||
|
||||
static STDMETHODIMP EnumConnectionPoints(IConnectionPointContainer *com_obj, IEnumConnectionPoints **enumPoints)
|
||||
{
|
||||
// The app had better know the GUIDs of whatever objects our
|
||||
// IMzObj supports for callbacks (ie, an IMzObjEvents), because
|
||||
// we're not going to bother providing him with an object to
|
||||
// enumerate the VTable GUIDs of all those supported objects
|
||||
*enumPoints = 0;
|
||||
return(E_NOTIMPL);
|
||||
}
|
||||
|
||||
static STDMETHODIMP FindConnectionPoint(IConnectionPointContainer *com_obj, REFIID vTableGuid, IConnectionPoint **ppv)
|
||||
{
|
||||
// Is the app asking us to return an IConnectionPoint object it can use
|
||||
// to give us its IMzObjEvents object? The app asks this by passing us
|
||||
// IMzObjEvents VTable's GUID (which we defined in IMzObj.h)
|
||||
if (IsEqualIID(vTableGuid, &DIID_IMzObjEvents))
|
||||
{
|
||||
MyRealMzObj *iExample;
|
||||
|
||||
// The app obviously wants to connect its IMzObjEvents object
|
||||
// to IMzObj. In order to do that, we need to give the app a
|
||||
// standard IConnectionPoint, so the app can call its Advise function
|
||||
// to give us its IMzObjEvents. This is easy to do since we embedded both
|
||||
// our IConnectionPointContainer and IConnectionPoint inside of our
|
||||
// IMzObj. All we need is a little pointer arithmetic
|
||||
iExample = (MyRealMzObj *)((char *)com_obj - offsetof(MyRealMzObj, container));
|
||||
*ppv = &iExample->point;
|
||||
|
||||
// Because we're giving the app a pointer to our IConnectionPoint, and
|
||||
// our IConnectionPoint is a sub-object of IMzObj, we need to
|
||||
// increment IMzObj's reference count. The easiest way to do this is to call
|
||||
// our IConnectionPointContainer's AddRef, because all we do there is delegate
|
||||
// to our IMzObj's AddRef
|
||||
AddRef_Connect(com_obj);
|
||||
|
||||
return(S_OK);
|
||||
}
|
||||
|
||||
// We don't support any other app objects connecting to IMzObj
|
||||
// events. All we've defined, and support, is an IMzObjEvents object. Tell
|
||||
// the app we don't know anything about the GUID he passed to us, and
|
||||
// do not give him any IConnectPoint object
|
||||
*ppv = 0;
|
||||
return(E_NOINTERFACE);
|
||||
}
|
||||
|
||||
|
||||
static const IConnectionPointContainerVtbl IConnectionPointContainer_Vtbl = {QueryInterface_Connect,
|
||||
AddRef_Connect,
|
||||
Release_Connect,
|
||||
EnumConnectionPoints,
|
||||
FindConnectionPoint};
|
||||
|
||||
// Our IConnectionPoint sub-object (for IMzObj) ////////////////////////////
|
||||
|
||||
static STDMETHODIMP QueryInterface_Point(IConnectionPoint *com_obj, REFIID vTableGuid, void **ppv)
|
||||
{
|
||||
// Because this is a sub-object of our IMzObj (ie, MyRealMzObj) object,
|
||||
// we delegate to IMzObj's QueryInterface. And because we embedded the
|
||||
// IConnectionPoint directly inside of MyRealMzObj, all we need
|
||||
// is a little pointer arithmetic to get our IMzObj
|
||||
return(QueryInterface((IMzObj *)((char *)com_obj - offsetof(MyRealMzObj, point)), vTableGuid, ppv));
|
||||
}
|
||||
|
||||
static STDMETHODIMP_(ULONG) AddRef_Point(IConnectionPoint *com_obj)
|
||||
{
|
||||
// Because we're a sub-object of IMzObj, delegate to its AddRef()
|
||||
// in order to increment IMzObj's reference count
|
||||
return(AddRef((IMzObj *)((char *)com_obj - offsetof(MyRealMzObj, point))));
|
||||
}
|
||||
|
||||
static STDMETHODIMP_(ULONG) Release_Point(IConnectionPoint *com_obj)
|
||||
{
|
||||
// Because we're a sub-object of IMzObj, delegate to its Release()
|
||||
// in order to decrement IMzObj's reference count
|
||||
return(Release((IMzObj *)((char *)com_obj - offsetof(MyRealMzObj, point))));
|
||||
}
|
||||
|
||||
// Called by the app to get our IMzObjEvents VTable's GUID (which we defined in IMzObj.h).
|
||||
// The app would call GetConnectionInterface() if it didn't link with IMzObj.h, and
|
||||
// therefore doesn't know our IMzObjEvents VTable's GUID. The app needs to know this GUID
|
||||
// because our Advise function below is going to pass this same GUID to some app object's
|
||||
// QueryInterface. The app's QueryInterface had better recognize this GUID if it intends
|
||||
// to honor our request to give us its IMzObjEvents object
|
||||
static STDMETHODIMP GetConnectionInterface(IConnectionPoint *com_obj, IID *vTableGuid)
|
||||
{
|
||||
// Tell the app to recognize our IMzObjEvents VTable GUID (defined as
|
||||
// DIID_IFeedback in IMzObj.h) when our Advise function calls
|
||||
// some app QueryInterface function
|
||||
CopyMemory(vTableGuid, &DIID_IMzObjEvents, sizeof(GUID));
|
||||
return(S_OK);
|
||||
}
|
||||
|
||||
// Called by the app to get the IConnectionPointContainer sub-object for our
|
||||
// IMzObj object.
|
||||
static STDMETHODIMP GetConnectionPointContainer(IConnectionPoint *com_obj, IConnectionPointContainer **ppv)
|
||||
{
|
||||
MyRealMzObj *iExample;
|
||||
|
||||
// Get the MyRealMzObj that this IConnectionPoint sub-object belongs
|
||||
// to. Because this IConnectPoint sub-object is embedded directly inside its
|
||||
// MyRealMzObj, all we need is a little pointer arithmetic
|
||||
iExample = (MyRealMzObj *)((char *)com_obj - offsetof(MyRealMzObj, point));
|
||||
|
||||
// Because the IConnectionPointContainer sub-object is also embedded right inside
|
||||
// the same MyRealMzObj, we can get a pointer to it easily as so
|
||||
*ppv = &iExample->container;
|
||||
|
||||
// Because we're giving the app a pointer to our IConnectionPointContainer, and
|
||||
// our IConnectionPointContainer is a sub-object of IMzObj, we need to
|
||||
// increment IMzObj's reference count. The easiest way to do this is to call
|
||||
// our IConnectionPoint's AddRef, because all we do there is delegate
|
||||
// to our IMzObj's AddRef
|
||||
AddRef_Point(com_obj);
|
||||
|
||||
return(S_OK);
|
||||
}
|
||||
|
||||
// Called by the app to give us its IMzObjEvents object. Actually, the app doesn't
|
||||
// just give us its IMzObjEvents. Rather, the app calls our Advise, passing us some
|
||||
// app object from which we can request the app to give us its IMzObjEvents. All of
|
||||
// this convoluted stuff is a combination of poor pre-planning by Microsoft
|
||||
// programmers when they designed this stuff, as well as the colossal blunder of
|
||||
// designing COM to accomodate the limitations of early, primitive editions of
|
||||
// Visual Basic.
|
||||
//
|
||||
// The second arg passed here is some app object whose QueryInterface function
|
||||
// we call to request the app's IMzObjEvents. We pass the GUID DIID_IMzObjEvents to
|
||||
// this QueryInterface in order to tell the app to give us its IMzObjEvents
|
||||
static STDMETHODIMP Advise(IConnectionPoint *com_obj, IUnknown *obj, DWORD *cookie)
|
||||
{
|
||||
HRESULT hr;
|
||||
MyRealMzObj *iExample;
|
||||
|
||||
// Get the MyRealMzObj that this IConnectionPoint sub-object belongs
|
||||
// to. Because this IConnectPoint sub-object is embedded directly inside its
|
||||
// MyRealMzObj, all we need is a little pointer arithmetic
|
||||
iExample = (MyRealMzObj *)((char *)com_obj - offsetof(MyRealMzObj, point));
|
||||
|
||||
// We allow only one IMzObjEvents for our IMzObj, so see if the app already
|
||||
// called our Advise(), and we got one. If so, let the app know that it is trying
|
||||
// to give us more IFeedbacks2 than we allow
|
||||
if (iExample->evts) return(CONNECT_E_ADVISELIMIT);
|
||||
|
||||
// Ok, we haven't yet gotten the one IMzObjEvents we allow from the app. Get the app's
|
||||
// IMzObjEvents object. We do this by calling the QueryInterface function of the
|
||||
// app object passed to us. We pass IMzObjEvents VTable's GUID (which we defined
|
||||
// in IMzObj.h).
|
||||
//
|
||||
// Save the app's IMzObjEvents pointer in our IMzObj feedback member, so we
|
||||
// can get it when we need it
|
||||
hr = obj->lpVtbl->QueryInterface(obj, &DIID_IMzObjEvents, (void **)&iExample->evts);
|
||||
|
||||
// We need to return (to the app) some value that will clue our Unadvise() function
|
||||
// below how to locate this app IMzObjEvents. The simpliest thing is to just use the
|
||||
// app's IMzObjEvents pointer as that returned value
|
||||
*cookie = (DWORD)iExample->evts;
|
||||
|
||||
return(hr);
|
||||
}
|
||||
|
||||
// Called by the app to tell us to stop using, and Release(), its IMzObjEvents object.
|
||||
// The second arg passed here is the value our Advise() function above returned when
|
||||
// we got the IMzObjEvents from the app. This value should help us locate wherever we
|
||||
// stored that IMzObjEvents pointer we got in Advise()
|
||||
static STDMETHODIMP Unadvise(IConnectionPoint *com_obj, DWORD cookie)
|
||||
{
|
||||
MyRealMzObj *iExample;
|
||||
|
||||
// Get the MyRealMzObj that this IConnectionPoint sub-object belongs
|
||||
// to. Because this IConnectPoint sub-object is embedded directly inside its
|
||||
// MyRealMzObj, all we need is a little pointer arithmetic
|
||||
iExample = (MyRealMzObj *)((char *)com_obj - offsetof(MyRealMzObj, point));
|
||||
|
||||
// Use the passed value to find wherever we stored his IMzObjEvents pointer.
|
||||
// Well, since we allow only one IMzObjEvents for our IMzObj, we already
|
||||
// know we stored it in our IMzObj->feedback member. And Advise()
|
||||
// returned that pointer as the "cookie" value. So we already got the
|
||||
// IMzObjEvents right now.
|
||||
//
|
||||
// Let's just make sure the cookie he passed is really the pointer we expect
|
||||
if (cookie && (IMzObjEvents *)cookie == iExample->evts)
|
||||
{
|
||||
// Release the app's IMzObjEvents
|
||||
((IMzObjEvents *)cookie)->lpVtbl->Release((IMzObjEvents *)cookie);
|
||||
|
||||
// We no longer have the app's IMzObjEvents, so clear the IMzObj
|
||||
// feedback member
|
||||
iExample->evts = 0;
|
||||
|
||||
return(S_OK);
|
||||
}
|
||||
return(CONNECT_E_NOCONNECTION);
|
||||
}
|
||||
|
||||
static STDMETHODIMP EnumConnections(IConnectionPoint *com_obj, IEnumConnections **enumConnects)
|
||||
{
|
||||
*enumConnects = 0;
|
||||
return(E_NOTIMPL);
|
||||
}
|
||||
|
||||
|
||||
static const IConnectionPointVtbl IConnectionPoint_Vtbl = {
|
||||
QueryInterface_Point,
|
||||
AddRef_Point,
|
||||
Release_Point,
|
||||
GetConnectionInterface,
|
||||
GetConnectionPointContainer,
|
||||
Advise,
|
||||
Unadvise,
|
||||
EnumConnections};
|
||||
|
||||
// The IClassFactory object ///////////////////////////////////////////////////////
|
||||
|
||||
// Since we only ever need one IClassFactory object, we declare
|
||||
// it static. The only requirement is that we ensure any
|
||||
// access to its members is thread-safe
|
||||
static IClassFactory MyIClassFactoryObj;
|
||||
|
||||
// IClassFactory's AddRef()
|
||||
static ULONG STDMETHODCALLTYPE classAddRef(IClassFactory *com_obj)
|
||||
{
|
||||
// Someone is obtaining my IClassFactory, so inc the count of
|
||||
// pointers that I've returned which some app needs to Release()
|
||||
InterlockedIncrement(&OutstandingObjects);
|
||||
|
||||
// Since we never actually allocate/free an IClassFactory (ie, we
|
||||
// use just 1 static one), we don't need to maintain a separate
|
||||
// reference count for our IClassFactory. We'll just tell the caller
|
||||
// that there's at least one of our IClassFactory objects in existance
|
||||
return(1);
|
||||
}
|
||||
|
||||
// IClassFactory's QueryInterface()
|
||||
static HRESULT STDMETHODCALLTYPE classQueryInterface(IClassFactory *com_obj, REFIID factoryGuid, void **ppv)
|
||||
{
|
||||
// Make sure the caller wants either an IUnknown or an IClassFactory.
|
||||
// In either case, we return the same IClassFactory pointer passed to
|
||||
// us since it can also masquerade as an IUnknown
|
||||
if (IsEqualIID(factoryGuid, &IID_IUnknown) || IsEqualIID(factoryGuid, &IID_IClassFactory))
|
||||
{
|
||||
// Call my IClassFactory's AddRef
|
||||
com_obj->lpVtbl->AddRef(com_obj);
|
||||
|
||||
// Return (to the caller) a ptr to my IClassFactory
|
||||
*ppv = com_obj;
|
||||
|
||||
return(NOERROR);
|
||||
}
|
||||
|
||||
// We don't know about any other GUIDs
|
||||
*ppv = 0;
|
||||
return(E_NOINTERFACE);
|
||||
}
|
||||
|
||||
// IClassFactory's Release()
|
||||
static ULONG STDMETHODCALLTYPE classRelease(IClassFactory *com_obj)
|
||||
{
|
||||
// One less object that an app has not yet Release()'ed
|
||||
return(InterlockedDecrement(&OutstandingObjects));
|
||||
}
|
||||
|
||||
// IClassFactory's CreateInstance() function. It is called by
|
||||
// someone who has a pointer to our IClassFactory object and now
|
||||
// wants to create and retrieve a pointer to our MzObj
|
||||
static HRESULT STDMETHODCALLTYPE classCreateInstance(IClassFactory *com_obj, IUnknown *punkOuter, REFIID vTableGuid, void **objHandle)
|
||||
{
|
||||
HRESULT hr;
|
||||
IMzObj *thisobj;
|
||||
|
||||
// Assume an error by clearing caller's handle
|
||||
*objHandle = 0;
|
||||
|
||||
// We don't support aggregation in this example
|
||||
if (punkOuter)
|
||||
hr = CLASS_E_NOAGGREGATION;
|
||||
else
|
||||
{
|
||||
// Allocate our MzObj object (actually a MyRealMzObj)
|
||||
if (!(thisobj = (IMzObj *)GlobalAlloc(GMEM_FIXED, sizeof(MyRealMzObj))))
|
||||
hr = E_OUTOFMEMORY;
|
||||
else
|
||||
{
|
||||
// Store MzObj's VTable in the object
|
||||
thisobj->lpVtbl = (IMzObjVtbl *)&IMzObj_Vtbl;
|
||||
|
||||
// Our MyRealIMzObj is a multiple interface object. It has an
|
||||
// IConnectionPointContainer sub-object embedded directly inside of
|
||||
// it. And we just allocated it when we allocated the MyRealIMzObj
|
||||
// above. Now we need to set its VTable into its lpVtbl member and
|
||||
// we're done initializing this sub-object
|
||||
((MyRealMzObj *)thisobj)->container.lpVtbl = (IConnectionPointContainerVtbl *)&IConnectionPointContainer_Vtbl;
|
||||
|
||||
// Our MyRealIMzObj also has an IConnectionPoint sub-object
|
||||
// embedded directly inside of it. And we just allocated it when we
|
||||
// allocated the MyRealIMzObj above. Now we need to set its
|
||||
// VTable into its lpVtbl member and we're done initializing this sub-object
|
||||
((MyRealMzObj *)thisobj)->point.lpVtbl = (IConnectionPointVtbl *)&IConnectionPoint_Vtbl;
|
||||
|
||||
// Increment the reference count so we can call Release() below and
|
||||
// it will deallocate only if there is an error with QueryInterface()
|
||||
((MyRealMzObj *)thisobj)->count = 1;
|
||||
|
||||
// Initialize any other members we added to the MzObj. We added
|
||||
// a string member
|
||||
((MyRealMzObj *)thisobj)->obj = new_mzobj(thisobj);
|
||||
|
||||
((MyRealMzObj *)thisobj)->evts = NULL;
|
||||
|
||||
// Fill in the caller's handle with a pointer to the MzObj we just
|
||||
// allocated above. We'll let MzObj's QueryInterface do that, because
|
||||
// it also checks the GUID the caller passed, and also increments the
|
||||
// reference count (to 2) if all goes well
|
||||
hr = IMzObj_Vtbl.QueryInterface(thisobj, vTableGuid, objHandle);
|
||||
|
||||
// Decrement reference count. NOTE: If there was an error in QueryInterface()
|
||||
// then Release() will be decrementing the count back to 0 and will free the
|
||||
// MzObj for us. One error that may occur is that the caller is asking for
|
||||
// some sort of object that we don't support (ie, it's a GUID we don't recognize)
|
||||
IMzObj_Vtbl.Release(thisobj);
|
||||
|
||||
// If success, inc static object count to keep this DLL loaded
|
||||
if (!hr) InterlockedIncrement(&OutstandingObjects);
|
||||
}
|
||||
}
|
||||
|
||||
return(hr);
|
||||
}
|
||||
|
||||
// IClassFactory's LockServer(). It is called by someone
|
||||
// who wants to lock this DLL in memory
|
||||
static HRESULT STDMETHODCALLTYPE classLockServer(IClassFactory *com_obj, BOOL flock)
|
||||
{
|
||||
if (flock) InterlockedIncrement(&LockCount);
|
||||
else InterlockedDecrement(&LockCount);
|
||||
|
||||
return(NOERROR);
|
||||
}
|
||||
|
||||
// IClassFactory's VTable
|
||||
static const IClassFactoryVtbl IClassFactory_Vtbl = {classQueryInterface,
|
||||
classAddRef,
|
||||
classRelease,
|
||||
classCreateInstance,
|
||||
classLockServer};
|
||||
|
||||
|
||||
|
||||
// Miscellaneous functions ///////////////////////////////////////////////////////
|
||||
|
||||
static DWORD reg_cookie;
|
||||
|
||||
HRESULT com_register()
|
||||
{
|
||||
// Initialize my IClassFactory with the pointer to its vtable
|
||||
MyIClassFactoryObj.lpVtbl = (IClassFactoryVtbl *)&IClassFactory_Vtbl;
|
||||
|
||||
return CoRegisterClassObject(&CLSID_IMzObj, &MyIClassFactoryObj,
|
||||
CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, ®_cookie);
|
||||
}
|
||||
|
||||
int com_can_unregister()
|
||||
/* called from multiple threads */
|
||||
{
|
||||
/* Note that OutstandingObjects will stay at least 1 after the class is registered. */
|
||||
return !((OutstandingObjects > 1) || (LockCount > 0));
|
||||
}
|
||||
|
||||
int com_unregister()
|
||||
{
|
||||
// If someone has retrieved pointers to any of our objects, and
|
||||
// not yet Release()'ed them, then we return S_FALSE to indicate
|
||||
// not to unload this DLL. Also, if someone has us locked, return
|
||||
// S_FALSE
|
||||
if (!com_can_unregister())
|
||||
return 0;
|
||||
else {
|
||||
if (MyTypeInfo) MyTypeInfo->lpVtbl->Release(MyTypeInfo);
|
||||
CoRevokeClassObject(reg_cookie);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
const GUID com_get_class_iid()
|
||||
{
|
||||
return IID_IMzObj;
|
||||
}
|
75
racket/src/mzcom/com_glue.h
Normal file
75
racket/src/mzcom/com_glue.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
#ifndef _COM_GLUE_H_
|
||||
#define _COM_GLUE_H_
|
||||
|
||||
#ifdef FOR_GLUE
|
||||
|
||||
#include <initguid.h>
|
||||
|
||||
// {A604CB9C-2AB5-11D4-B6D3-0060089002FE}
|
||||
DEFINE_GUID(CLSID_TypeLib, 0xA604CB9C, 0x2ab5, 0x11d4, 0xb6, 0xd3, 0x00, 0x60, 0x08, 0x90, 0x02, 0xfe);
|
||||
|
||||
// {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}
|
||||
DEFINE_GUID(CLSID_IMzObj, 0xA3B0AF9E, 0x2ab0, 0x11d4, 0xb6, 0xd2, 0x00, 0x60, 0x08, 0x90, 0x02, 0xfe);
|
||||
|
||||
// {A604CBA8-2AB5-11D4-B6D3-0060089002FE}
|
||||
DEFINE_GUID(IID_IMzObj, 0xA604CBA8, 0x2ab5, 0x11d4, 0xb6, 0xd3, 0x00, 0x60, 0x08, 0x90, 0x02, 0xfe);
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IMzObj
|
||||
DECLARE_INTERFACE_ (INTERFACE, IDispatch)
|
||||
{
|
||||
// IUnknown functions
|
||||
STDMETHOD (QueryInterface) (THIS_ REFIID, void **) PURE;
|
||||
STDMETHOD_ (ULONG, AddRef) (THIS) PURE;
|
||||
STDMETHOD_ (ULONG, Release) (THIS) PURE;
|
||||
// IDispatch functions
|
||||
STDMETHOD_ (ULONG, GetTypeInfoCount)(THIS_ UINT *) PURE;
|
||||
STDMETHOD_ (ULONG, GetTypeInfo) (THIS_ UINT, LCID, ITypeInfo **) PURE;
|
||||
STDMETHOD_ (ULONG, GetIDsOfNames) (THIS_ REFIID, LPOLESTR *, UINT, LCID, DISPID *) PURE;
|
||||
STDMETHOD_ (ULONG, Invoke) (THIS_ DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *) PURE;
|
||||
// Extra functions
|
||||
STDMETHOD (Eval) (THIS_ BSTR, BSTR *) PURE;
|
||||
STDMETHOD (About) (THIS) PURE;
|
||||
STDMETHOD (Reset) (THIS) PURE;
|
||||
};
|
||||
|
||||
// {A604CBA9-2AB5-11D4-B6D3-0060089002FE}
|
||||
DEFINE_GUID(DIID_IMzObjEvents, 0xA604CBA9, 0x2ab5, 0x11d4, 0xb6, 0xd3, 0x00, 0x60, 0x08, 0x90, 0x02, 0xfe);
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IMzObjEvents
|
||||
DECLARE_INTERFACE_ (INTERFACE, IDispatch)
|
||||
{
|
||||
// IUnknown functions
|
||||
STDMETHOD (QueryInterface) (THIS_ REFIID, void **) PURE;
|
||||
STDMETHOD_ (ULONG, AddRef) (THIS) PURE;
|
||||
STDMETHOD_ (ULONG, Release) (THIS) PURE;
|
||||
// IDispatch functions
|
||||
STDMETHOD_ (ULONG, GetTypeInfoCount)(THIS_ UINT *) PURE;
|
||||
STDMETHOD_ (ULONG, GetTypeInfo) (THIS_ UINT, LCID, ITypeInfo **) PURE;
|
||||
STDMETHOD_ (ULONG, GetIDsOfNames) (THIS_ REFIID, LPOLESTR *, UINT, LCID, DISPID *) PURE;
|
||||
STDMETHOD_ (ULONG, Invoke) (THIS_ DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *) PURE;
|
||||
// Extra functions
|
||||
STDMETHOD (SchemeError) (THIS_ BSTR *) PURE;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
typedef struct IMzObj { int dummy; } IMzObj;
|
||||
|
||||
#endif
|
||||
|
||||
extern HRESULT com_register();
|
||||
extern int com_unregister();
|
||||
extern int com_can_unregister();
|
||||
extern const GUID com_get_class_iid();
|
||||
|
||||
extern void *new_mzobj(IMzObj*);
|
||||
extern void delete_mzobj(void*);
|
||||
extern HRESULT mzobj_about(void*);
|
||||
extern HRESULT mzobj_reset(void*);
|
||||
extern HRESULT mzobj_eval(void*, BSTR, BSTR*);
|
||||
|
||||
extern VOID Fire_SchemeError(IMzObj *com_obj, BSTR description);
|
||||
|
||||
#endif // _COM_GLUE_H_
|
|
@ -3,96 +3,101 @@
|
|||
// This file is not xformed for 3m. There's just one
|
||||
// bit of conditional compilation on MZCOM_3M.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "../racket/src/schvers.h"
|
||||
#include "resource.h"
|
||||
#include <initguid.h>
|
||||
#include "mzcom.h"
|
||||
|
||||
#include "mzcom_i.c"
|
||||
#include "mzobj.h"
|
||||
#include <objbase.h>
|
||||
extern "C" {
|
||||
#include "com_glue.h"
|
||||
};
|
||||
|
||||
// time for EXE to be idle before shutting down
|
||||
#define dwTimeOut (5000)
|
||||
// time to wait for threads to finish up
|
||||
#define dwPause (1000)
|
||||
|
||||
HINSTANCE globHinst;
|
||||
|
||||
// Passed to CreateThread to monitor the shutdown event
|
||||
/* A monitor thread might be a good idea to make sure the process
|
||||
terminates if it's somehow started and not used. It also creates
|
||||
a race condition, though, so it's disabled for now. */
|
||||
|
||||
#if 0
|
||||
|
||||
// time for EXE to be idle before shutting down
|
||||
#define dwTimeOut (5000)
|
||||
|
||||
static HANDLE hEventShutdown;
|
||||
static DWORD dwThreadID;
|
||||
|
||||
// Polls for idle state
|
||||
static DWORD WINAPI MonitorProc(void* pv)
|
||||
{
|
||||
CExeModule* p = (CExeModule*)pv;
|
||||
p->MonitorShutdown();
|
||||
return 0;
|
||||
while (1) {
|
||||
DWORD dwWait=0;
|
||||
do
|
||||
{
|
||||
dwWait = WaitForSingleObject(hEventShutdown, dwTimeOut);
|
||||
} while (dwWait == WAIT_OBJECT_0);
|
||||
|
||||
if (com_can_unregister())
|
||||
break;
|
||||
}
|
||||
CloseHandle(hEventShutdown);
|
||||
PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG CExeModule::Unlock()
|
||||
static bool StartMonitor()
|
||||
{
|
||||
LONG l = CComModule::Unlock();
|
||||
if (l == 0)
|
||||
{
|
||||
bActivity = true;
|
||||
SetEvent(hEventShutdown);
|
||||
}
|
||||
return l;
|
||||
dwThreadID = GetCurrentThreadId();
|
||||
hEventShutdown = CreateEvent(NULL, false, false, NULL);
|
||||
if (hEventShutdown == NULL)
|
||||
return false;
|
||||
|
||||
DWORD subThreadID;
|
||||
HANDLE h = CreateThread(NULL, 0, MonitorProc, NULL, 0, &subThreadID);
|
||||
return (h != NULL);
|
||||
}
|
||||
|
||||
// Monitors the shutdown event
|
||||
void CExeModule::MonitorShutdown()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
WaitForSingleObject(hEventShutdown, INFINITE);
|
||||
DWORD dwWait=0;
|
||||
do
|
||||
{
|
||||
bActivity = false;
|
||||
dwWait = WaitForSingleObject(hEventShutdown, dwTimeOut);
|
||||
} while (dwWait == WAIT_OBJECT_0);
|
||||
// timed out
|
||||
if (!bActivity && m_nLockCnt == 0) // if no activity let's really bail
|
||||
{
|
||||
#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
|
||||
CoSuspendClassObjects();
|
||||
if (!bActivity && m_nLockCnt == 0)
|
||||
#else
|
||||
|
||||
static bool StartMonitor() { return TRUE; }
|
||||
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
CloseHandle(hEventShutdown);
|
||||
PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
|
||||
}
|
||||
|
||||
bool CExeModule::StartMonitor()
|
||||
static int set_reg_string(HKEY sub, char *name, char *s)
|
||||
{
|
||||
hEventShutdown = CreateEvent(NULL, false, false, NULL);
|
||||
if (hEventShutdown == NULL)
|
||||
return false;
|
||||
DWORD dwThreadID;
|
||||
HANDLE h = CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
|
||||
return (h != NULL);
|
||||
return RegSetValueExA(sub, name, 0, REG_SZ, (const BYTE *)s, strlen(s));
|
||||
}
|
||||
|
||||
CExeModule _Module;
|
||||
static int set_reg_sub_string(HKEY sub, char *name, char *s)
|
||||
{
|
||||
HKEY sub2;
|
||||
int nRet;
|
||||
|
||||
BEGIN_OBJECT_MAP(ObjectMap)
|
||||
OBJECT_ENTRY(CLSID_MzObj, CMzObj)
|
||||
END_OBJECT_MAP()
|
||||
nRet = RegCreateKeyExA(sub, name, 0, NULL, 0, KEY_SET_VALUE, NULL, &sub2, NULL);
|
||||
if (!nRet) {
|
||||
nRet |= set_reg_string(sub2, NULL, s);
|
||||
nRet |= RegCloseKey(sub2);
|
||||
}
|
||||
|
||||
return nRet;
|
||||
}
|
||||
|
||||
LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
|
||||
{
|
||||
while (p1 != NULL && *p1 != NULL)
|
||||
while (p1 != NULL && *p1 != NULL)
|
||||
{
|
||||
LPCTSTR p = p2;
|
||||
while (p != NULL && *p != NULL)
|
||||
LPCTSTR p = p2;
|
||||
while (p != NULL && *p != NULL)
|
||||
{
|
||||
if (*p1 == *p)
|
||||
return CharNext(p1);
|
||||
p = CharNext(p);
|
||||
if (*p1 == *p)
|
||||
return CharNext(p1);
|
||||
p = CharNext(p);
|
||||
}
|
||||
p1 = CharNext(p1);
|
||||
p1 = CharNext(p1);
|
||||
}
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int IsFlag(LPCTSTR cmd, LPCTSTR flag)
|
||||
|
@ -122,8 +127,8 @@ int IsFlag(LPCTSTR cmd, LPCTSTR flag)
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
|
||||
HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/) {
|
||||
extern "C" int WINAPI WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/) {
|
||||
|
||||
globHinst = hInstance;
|
||||
|
||||
|
@ -136,98 +141,160 @@ extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
|
|||
load_delayed_dll(hInstance, "libracketxxxxxxx.dll");
|
||||
#endif
|
||||
|
||||
#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
|
||||
HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
#else
|
||||
HRESULT hRes = CoInitialize(NULL);
|
||||
#endif
|
||||
_ASSERTE(SUCCEEDED(hRes));
|
||||
_Module.Init(ObjectMap, hInstance, &LIBID_MZCOMLib);
|
||||
_Module.dwThreadID = GetCurrentThreadId();
|
||||
HRESULT nRet = CoInitialize(NULL);
|
||||
|
||||
int argc, i;
|
||||
char **argv, *normalized_path;
|
||||
|
||||
argv = cmdline_to_argv(&argc, &normalized_path);
|
||||
|
||||
int nRet = 0, verbose = 0;
|
||||
int verbose = 0;
|
||||
BOOL bRun = TRUE;
|
||||
LPCTSTR lpszToken;
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
lpszToken = argv[i];
|
||||
if (IsFlag(lpszToken, _T("UnregServer")))
|
||||
if (IsFlag(lpszToken, "UnregServer"))
|
||||
{
|
||||
if (!nRet) {
|
||||
_Module.UpdateRegistryFromResource(IDR_MZCOM, FALSE);
|
||||
nRet = _Module.UnregisterServer(TRUE);
|
||||
HKEY sub;
|
||||
|
||||
nRet |= RegDeleteKeyA(HKEY_CLASSES_ROOT, "MzCOM.MzObj");
|
||||
nRet |= RegDeleteKeyA(HKEY_CLASSES_ROOT, "MzCOM.MzObj." MZSCHEME_VERSION);
|
||||
|
||||
if (!nRet) {
|
||||
nRet = RegCreateKeyExA(HKEY_CLASSES_ROOT, "CLSID", 0, NULL, 0, KEY_SET_VALUE, NULL, &sub, NULL);
|
||||
if (!nRet) {
|
||||
nRet |= RegDeleteKeyA(sub, "{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}");
|
||||
nRet |= RegCloseKey(sub);
|
||||
}
|
||||
}
|
||||
|
||||
if (!nRet) {
|
||||
nRet = RegCreateKeyExA(HKEY_CLASSES_ROOT, "AppID", 0, NULL, 0, KEY_SET_VALUE, NULL, &sub, NULL);
|
||||
if (!nRet) {
|
||||
nRet |= RegDeleteKeyA(sub, "{A604CB9D-2AB5-11D4-B6D3-0060089002FE}");
|
||||
nRet |= RegCloseKey(sub);
|
||||
}
|
||||
}
|
||||
|
||||
bRun = FALSE;
|
||||
}
|
||||
}
|
||||
else if (IsFlag(lpszToken, _T("RegServer")))
|
||||
else if (IsFlag(lpszToken, "RegServer"))
|
||||
{
|
||||
if (!nRet) {
|
||||
_Module.UpdateRegistryFromResource(IDR_MZCOM, TRUE);
|
||||
nRet = _Module.RegisterServer(TRUE);
|
||||
HKEY sub, sub2;
|
||||
|
||||
nRet |= RegCreateKeyExA(HKEY_CLASSES_ROOT, "MzCOM.MzObj", 0, NULL, 0, KEY_SET_VALUE, NULL, &sub, NULL);
|
||||
|
||||
if (!nRet) {
|
||||
nRet |= set_reg_string(sub, NULL, "MzObj Class");
|
||||
nRet |= set_reg_sub_string(sub, "CLSID", "{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}");
|
||||
nRet |= set_reg_sub_string(sub, "CurVer", "MzCOM.MzObj." MZSCHEME_VERSION);
|
||||
nRet |= RegCloseKey(sub);
|
||||
}
|
||||
|
||||
if (!nRet) {
|
||||
nRet = RegCreateKeyExA(HKEY_CLASSES_ROOT, "MzCOM.MzObj." MZSCHEME_VERSION, 0, NULL, 0, KEY_SET_VALUE, NULL, &sub, NULL);
|
||||
if (!nRet) {
|
||||
nRet |= set_reg_string(sub, NULL, "MzObj Class");
|
||||
nRet |= set_reg_sub_string(sub, "CLSID", "{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}");
|
||||
nRet |= RegCloseKey(sub);
|
||||
}
|
||||
}
|
||||
|
||||
if (!nRet) {
|
||||
nRet = RegCreateKeyExA(HKEY_CLASSES_ROOT, "CLSID", 0, NULL, 0, KEY_SET_VALUE, NULL, &sub, NULL);
|
||||
if (!nRet) {
|
||||
nRet = RegCreateKeyExA(sub, "{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}", 0, NULL, 0, KEY_SET_VALUE, NULL, &sub2, NULL);
|
||||
if (!nRet) {
|
||||
nRet |= set_reg_string(sub2, NULL, "MzObj Class");
|
||||
nRet |= set_reg_string(sub2, "AppId", "{A604CB9D-2AB5-11D4-B6D3-0060089002FE}");
|
||||
nRet |= set_reg_sub_string(sub2, "ProgID", "MzCOM.MzObj." MZSCHEME_VERSION);
|
||||
nRet |= set_reg_sub_string(sub2, "VersionIndependentProgID", "MzCOM.MzObj");
|
||||
nRet |= set_reg_sub_string(sub2, "Programmable", "");
|
||||
|
||||
char *path;
|
||||
path = (char *)malloc(1024 * sizeof(wchar_t));
|
||||
GetModuleFileNameA(NULL, path, 1024);
|
||||
nRet |= set_reg_sub_string(sub2, "LocalServer32", path);
|
||||
free(path);
|
||||
|
||||
nRet |= set_reg_sub_string(sub2, "TypeLib", "{A604CB9C-2AB5-11D4-B6D3-0060089002FE}");
|
||||
nRet |= RegCloseKey(sub2);
|
||||
}
|
||||
nRet |= RegCloseKey(sub);
|
||||
}
|
||||
}
|
||||
|
||||
if (!nRet) {
|
||||
nRet = RegCreateKeyExA(HKEY_CLASSES_ROOT, "AppID", 0, NULL, 0, KEY_SET_VALUE, NULL, &sub, NULL);
|
||||
if (!nRet) {
|
||||
nRet = RegCreateKeyExA(sub, "{A604CB9D-2AB5-11D4-B6D3-0060089002FE}", 0, NULL, 0, KEY_SET_VALUE, NULL, &sub2, NULL);
|
||||
if (!nRet) {
|
||||
nRet |= set_reg_string(sub2, NULL, "MzCOM");
|
||||
nRet |= RegCloseKey(sub2);
|
||||
}
|
||||
}
|
||||
if (!nRet) {
|
||||
nRet = RegCreateKeyExA(sub, "MzCOM.EXE", 0, NULL, 0, KEY_SET_VALUE, NULL, &sub2, NULL);
|
||||
if (!nRet) {
|
||||
nRet |= set_reg_string(sub2, "AppID", "{A604CB9D-2AB5-11D4-B6D3-0060089002FE}");
|
||||
nRet |= RegCloseKey(sub2);
|
||||
}
|
||||
}
|
||||
nRet |= RegCloseKey(sub);
|
||||
}
|
||||
|
||||
bRun = FALSE;
|
||||
}
|
||||
}
|
||||
else if (IsFlag(lpszToken, _T("v")))
|
||||
else if (IsFlag(lpszToken, "v"))
|
||||
{
|
||||
verbose = 1;
|
||||
}
|
||||
else if (IsFlag(lpszToken, _T("?")))
|
||||
else if (IsFlag(lpszToken, "?"))
|
||||
{
|
||||
MessageBox(NULL,
|
||||
_T("/RegServer - register\n"
|
||||
"/UnregServer - unregister\n"
|
||||
"/Embedding - ignored\n"
|
||||
"/v - report failures\n"
|
||||
"/? - show this help"),
|
||||
_T("Help"),
|
||||
"/RegServer - register\n"
|
||||
"/UnregServer - unregister\n"
|
||||
"/Embedding - ignored\n"
|
||||
"/v - report failures\n"
|
||||
"/? - show this help",
|
||||
"Help",
|
||||
MB_OK);
|
||||
bRun = FALSE;
|
||||
}
|
||||
else if (IsFlag(lpszToken, _T("Embedding")))
|
||||
else if (IsFlag(lpszToken, "Embedding"))
|
||||
{
|
||||
/* ??? */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verbose)
|
||||
MessageBox(NULL, lpszToken, _T("Unknown Flag"), MB_OK);
|
||||
MessageBox(NULL, lpszToken, "Unknown Flag", MB_OK);
|
||||
bRun = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bRun)
|
||||
{
|
||||
_Module.StartMonitor();
|
||||
if (bRun) {
|
||||
StartMonitor();
|
||||
|
||||
#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
|
||||
hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
|
||||
REGCLS_SINGLEUSE | REGCLS_SUSPENDED);
|
||||
// was: REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
|
||||
nRet = com_register();
|
||||
|
||||
|
||||
_ASSERTE(SUCCEEDED(hRes));
|
||||
hRes = CoResumeClassObjects();
|
||||
#else
|
||||
hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
|
||||
// was REGCLS_MULTIPLEUSE);
|
||||
REGCLS_SINGLEUSE);
|
||||
#endif
|
||||
_ASSERTE(SUCCEEDED(hRes));
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, 0, 0, 0))
|
||||
DispatchMessage(&msg);
|
||||
|
||||
_Module.RevokeClassObjects();
|
||||
Sleep(dwPause); //wait for any threads to finish
|
||||
if (!nRet) {
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, 0, 0, 0))
|
||||
DispatchMessage(&msg);
|
||||
|
||||
while (!com_unregister()) {
|
||||
Sleep(dwPause); // wait for any objects to finish
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (verbose && (nRet != 0)) {
|
||||
wchar_t *res;
|
||||
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||
|
@ -241,7 +308,7 @@ extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
|
|||
MessageBoxW(NULL, res, L"Registration Failed", MB_OK);
|
||||
}
|
||||
|
||||
_Module.Term();
|
||||
CoUninitialize();
|
||||
return nRet;
|
||||
CoUninitialize();
|
||||
|
||||
return nRet;
|
||||
}
|
||||
|
|
|
@ -12,10 +12,14 @@
|
|||
START_XFORM_SKIP;
|
||||
#endif
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include "mzcom.h"
|
||||
#include <process.h>
|
||||
|
||||
#include <objbase.h>
|
||||
extern "C" {
|
||||
#include "com_glue.h"
|
||||
};
|
||||
|
||||
#ifdef MZ_PRECISE_GC
|
||||
END_XFORM_SKIP;
|
||||
|
@ -332,7 +336,10 @@ void CMzObj::startMzThread(void) {
|
|||
}
|
||||
|
||||
|
||||
CMzObj::CMzObj(void) {
|
||||
CMzObj::CMzObj(void *_com_obj) {
|
||||
|
||||
com_obj = _com_obj;
|
||||
|
||||
inputMutex = NULL;
|
||||
readSem = NULL;
|
||||
threadHandle = NULL;
|
||||
|
@ -433,7 +440,7 @@ void CMzObj::RaiseError(const OLECHAR *msg) {
|
|||
|
||||
if (CreateErrorInfo(&pICreateErrorInfo) == S_OK &&
|
||||
pICreateErrorInfo != NULL) {
|
||||
pICreateErrorInfo->SetGUID(IID_IMzObj);
|
||||
pICreateErrorInfo->SetGUID(com_get_class_iid());
|
||||
pICreateErrorInfo->SetDescription((LPOLESTR)msg);
|
||||
pICreateErrorInfo->SetSource((LPOLESTR)L"MzCOM.MzObj");
|
||||
if (pICreateErrorInfo->QueryInterface(IID_IErrorInfo,
|
||||
|
@ -443,7 +450,7 @@ void CMzObj::RaiseError(const OLECHAR *msg) {
|
|||
}
|
||||
}
|
||||
|
||||
Fire_SchemeError(bstr);
|
||||
Fire_SchemeError((IMzObj *)com_obj, bstr);
|
||||
SysFreeString(bstr);
|
||||
}
|
||||
|
||||
|
@ -470,7 +477,7 @@ BOOL CMzObj::testThread(void) {
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMzObj
|
||||
|
||||
STDMETHODIMP CMzObj::Eval(BSTR input, BSTR *output) {
|
||||
HRESULT CMzObj::Eval(BSTR input, BSTR *output) {
|
||||
if (!testThread()) {
|
||||
return E_ABORT;
|
||||
}
|
||||
|
@ -515,12 +522,12 @@ INT_PTR WINAPI dlgProc(HWND hDlg,UINT msg,WPARAM wParam,LPARAM) {
|
|||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CMzObj::About() {
|
||||
HRESULT CMzObj::About() {
|
||||
DialogBox(globHinst,MAKEINTRESOURCE(ABOUTBOX),NULL,dlgProc);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMzObj::Reset() {
|
||||
HRESULT CMzObj::Reset() {
|
||||
if (!testThread()) {
|
||||
return E_ABORT;
|
||||
}
|
||||
|
@ -530,6 +537,31 @@ STDMETHODIMP CMzObj::Reset() {
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
void *new_mzobj(IMzObj *com_obj)
|
||||
{
|
||||
return new CMzObj(com_obj);
|
||||
}
|
||||
|
||||
void delete_mzobj(void *o)
|
||||
{
|
||||
delete (CMzObj *)o;
|
||||
}
|
||||
|
||||
HRESULT mzobj_about(void *o)
|
||||
{
|
||||
return ((CMzObj *)o)->About();
|
||||
}
|
||||
|
||||
HRESULT mzobj_reset(void *o)
|
||||
{
|
||||
return ((CMzObj *)o)->Reset();
|
||||
}
|
||||
|
||||
HRESULT mzobj_eval(void *o, BSTR s, BSTR *r)
|
||||
{
|
||||
return ((CMzObj *)o)->Eval(s, r);
|
||||
}
|
||||
|
||||
#ifdef MZ_PRECISE_GC
|
||||
END_XFORM_SKIP;
|
||||
#endif
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#define __MZOBJ_H_
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
#include "MzCOMCP.h"
|
||||
|
||||
typedef struct {
|
||||
BSTR **ppInput;
|
||||
|
@ -27,16 +26,13 @@ extern HINSTANCE globHinst;
|
|||
START_XFORM_SKIP;
|
||||
#endif
|
||||
|
||||
class ATL_NO_VTABLE CMzObj :
|
||||
public CComObjectRootEx<CComSingleThreadModel>,
|
||||
public CComCoClass<CMzObj, &CLSID_MzObj>,
|
||||
public IConnectionPointContainerImpl<CMzObj>,
|
||||
public IDispatchImpl<IMzObj, &IID_IMzObj, &LIBID_MZCOMLib>,
|
||||
public CProxy_IMzObjEvents< CMzObj >
|
||||
class CMzObj
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
void *com_obj;
|
||||
|
||||
HRESULT hr;
|
||||
HANDLE inputMutex;
|
||||
HANDLE readSem;
|
||||
|
@ -56,29 +52,14 @@ class ATL_NO_VTABLE CMzObj :
|
|||
|
||||
public:
|
||||
|
||||
CMzObj(void);
|
||||
CMzObj(void* com_obj);
|
||||
~CMzObj(void);
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_MZOBJ)
|
||||
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
BEGIN_COM_MAP(CMzObj)
|
||||
COM_INTERFACE_ENTRY(IMzObj)
|
||||
COM_INTERFACE_ENTRY(IDispatch)
|
||||
COM_INTERFACE_ENTRY(IConnectionPointContainer)
|
||||
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
|
||||
END_COM_MAP()
|
||||
BEGIN_CONNECTION_POINT_MAP(CMzObj)
|
||||
CONNECTION_POINT_ENTRY(DIID__IMzObjEvents)
|
||||
END_CONNECTION_POINT_MAP()
|
||||
|
||||
|
||||
// IMzObj
|
||||
public:
|
||||
STDMETHOD(Reset)(void);
|
||||
STDMETHOD(About)(void);
|
||||
STDMETHOD(Eval)(BSTR input,/*[out,retval]*/BSTR *output);
|
||||
HRESULT Reset(void);
|
||||
HRESULT About(void);
|
||||
HRESULT Eval(BSTR input,/*[out,retval]*/BSTR *output);
|
||||
};
|
||||
|
||||
#ifdef MZ_XFORM
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently,
|
||||
// but are changed infrequently
|
||||
|
||||
#if !defined(AFX_STDAFX_H__A604CB9F_2AB5_11D4_B6D3_0060089002FE__INCLUDED_)
|
||||
#define AFX_STDAFX_H__A604CB9F_2AB5_11D4_B6D3_0060089002FE__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#define STRICT
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#endif
|
||||
#define _ATL_APARTMENT_THREADED
|
||||
|
||||
#include <atlbase.h>
|
||||
//You may derive a class from CComModule and use it if you want to override
|
||||
//something, but do not change the name of _Module
|
||||
class CExeModule : public CComModule
|
||||
{
|
||||
public:
|
||||
LONG Unlock();
|
||||
DWORD dwThreadID;
|
||||
HANDLE hEventShutdown;
|
||||
void MonitorShutdown();
|
||||
bool StartMonitor();
|
||||
bool bActivity;
|
||||
};
|
||||
extern CExeModule _Module;
|
||||
|
||||
#include <atlcom.h>
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__A604CB9F_2AB5_11D4_B6D3_0060089002FE__INCLUDED)
|
|
@ -1,8 +1,9 @@
|
|||
This directory contains
|
||||
|
||||
- solution files and project files for building minimal Racket (and
|
||||
GRacket) with Microsoft Visual Studio 2008 (a.k.a. version 9.0)
|
||||
and up, which work with the Express version of Visual Studio;
|
||||
- solution files and project files for building minimal Racket and
|
||||
related executables with Microsoft Visual Studio 2008
|
||||
(a.k.a. version 9.0) and up, which work with the Express version
|
||||
of Visual Studio;
|
||||
|
||||
- mzconfig.h which is a manual version of information that is gathered
|
||||
automatically when using the "configure" script;
|
||||
|
@ -10,16 +11,11 @@ This directory contains
|
|||
- scripts for building 3m variants of Racket and GRacket using Visual
|
||||
Studio command-line tools;
|
||||
|
||||
- solution files and project files for building MzCOM with
|
||||
Microsoft Visual Studio 2008 (not Express, which doesn't support ATL
|
||||
and MFC);
|
||||
|
||||
- solution files and project files for building "myssink.dll" with
|
||||
Microsoft Visual Studio 2008, although the DLL is normally
|
||||
downloaded along with other pre-built DLLs.
|
||||
Microsoft Visual Studio 2008 (not Express), although the DLL is
|
||||
normally downloaded along with other pre-built DLLs.
|
||||
|
||||
Visual Studio Express is available for free from Microsoft; it can be
|
||||
used to build Racket and GRacket, but not MzCOM.
|
||||
Visual Studio Express is available for free from Microsoft.
|
||||
|
||||
Racket and GRacket also compile with MinGW. To compile with MinGW,
|
||||
follow the instructions in racket\src\README (which contains a short
|
||||
|
@ -192,9 +188,8 @@ updated to replace "xxxxxxxx" with a specific version number.
|
|||
Building MzCOM
|
||||
--------------
|
||||
|
||||
Beware that MzCOM does not build with Express versions of Visual
|
||||
Studio. Otherwise, building MzCOMCGC is similar to building
|
||||
RacketCGC. Building the 3m variant is a little different.
|
||||
Building MzCOMCGC is similar to building RacketCGC. Building the 3m
|
||||
variant is a little different.
|
||||
|
||||
To build MzCOMCGC, make the MzCOM solution in
|
||||
racket\src\worksp\mzcom - makes racket\MzCOMCGC.exe
|
||||
|
|
|
@ -24,14 +24,9 @@
|
|||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
UseOfATL="1"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="..\..\..\racket -c mzobj_rgs.rkt"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName="$(OutDir)\$(ProjectName).tlb"
|
||||
|
@ -64,6 +59,7 @@
|
|||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="..\..\..\lib\$(ProjectName)CGC.pdb"
|
||||
SubSystem="2"
|
||||
StackReserveSize="8388608"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
/>
|
||||
|
@ -75,14 +71,9 @@
|
|||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
UseOfATL="1"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="..\..\..\racket -c mzobj_rgs.rkt"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
|
@ -116,6 +107,7 @@
|
|||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="..\..\..\lib\$(ProjectName)CGC.pdb"
|
||||
SubSystem="2"
|
||||
StackReserveSize="8388608"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="17"
|
||||
|
@ -128,14 +120,9 @@
|
|||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
UseOfATL="1"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="..\..\..\racket -c mzobj_rgs.rkt"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName="$(OutDir)\$(ProjectName).tlb"
|
||||
|
@ -172,6 +159,7 @@
|
|||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="..\..\..\lib\$(ProjectName)CGC.pdb"
|
||||
SubSystem="2"
|
||||
StackReserveSize="8388608"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
/>
|
||||
|
@ -183,14 +171,9 @@
|
|||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
UseOfATL="1"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="..\..\..\racket -c mzobj_rgs.rkt"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
|
@ -228,6 +211,7 @@
|
|||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="..\..\..\lib\$(ProjectName)CGC.pdb"
|
||||
SubSystem="2"
|
||||
StackReserveSize="8388608"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="17"
|
||||
|
@ -240,14 +224,9 @@
|
|||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
UseOfATL="1"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="..\..\..\racket -c mzobj_rgs.rkt"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName="$(OutDir)\$(ProjectName).tlb"
|
||||
|
@ -285,6 +264,7 @@
|
|||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="..\..\..\lib\$(ProjectName).pdb"
|
||||
SubSystem="2"
|
||||
StackReserveSize="8388608"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
/>
|
||||
|
@ -296,14 +276,9 @@
|
|||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
UseOfATL="1"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="..\..\..\racket -c mzobj_rgs.rkt"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
|
@ -342,6 +317,7 @@
|
|||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="..\..\..\lib\$(ProjectName).pdb"
|
||||
SubSystem="2"
|
||||
StackReserveSize="8388608"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="17"
|
||||
|
@ -359,6 +335,10 @@
|
|||
RelativePath="..\..\mzcom\mzcom.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\mzcom\com_glue.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\mzcom\mzcom.idl"
|
||||
>
|
||||
|
@ -367,27 +347,19 @@
|
|||
RelativePath="..\..\mzcom\mzobj.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\mzcom\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\mzcom.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MzCOMCP.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\mzcom\mzobj.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\mzcom\com_glue.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
|
@ -401,14 +373,6 @@
|
|||
RelativePath=".\mzcom.rc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MzCOM.rgs"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MzObj.rgs"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
#ifndef _MZCOMCP_H_
|
||||
#define _MZCOMCP_H_
|
||||
|
||||
template <class T>
|
||||
class CProxy_IMzObjEvents : public IConnectionPointImpl<T, &DIID__IMzObjEvents, CComDynamicUnkArray>
|
||||
{
|
||||
//Warning this class may be recreated by the wizard.
|
||||
public:
|
||||
VOID Fire_SchemeError(BSTR description)
|
||||
{
|
||||
T* pT = static_cast<T*>(this);
|
||||
int nConnectionIndex;
|
||||
CComVariant* pvars = new CComVariant[1];
|
||||
int nConnections = m_vec.GetSize();
|
||||
|
||||
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
|
||||
{
|
||||
pT->Lock();
|
||||
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
|
||||
pT->Unlock();
|
||||
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
|
||||
if (pDispatch != NULL)
|
||||
{
|
||||
pvars[0] = description;
|
||||
DISPPARAMS disp = { pvars, NULL, 1, 0 };
|
||||
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
delete[] pvars;
|
||||
}
|
||||
};
|
||||
#endif
|
|
@ -6,5 +6,3 @@ The MzCOM source files are in plt/src/mzcom/.
|
|||
You'll also need the Racket sources to compile
|
||||
MzCOM. See plt/src/worksp/README for more information
|
||||
on compiling Racket.
|
||||
|
||||
Send questions to Paul Steckler, steck@racket-lang.org.
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
; MzCOM.def : Declares the module parameters.
|
||||
|
||||
LIBRARY "MzCOM.DLL"
|
||||
|
||||
EXPORTS
|
||||
DllCanUnloadNow @1 PRIVATE
|
||||
DllGetClassObject @2 PRIVATE
|
||||
DllRegisterServer @3 PRIVATE
|
||||
DllUnregisterServer @4 PRIVATE
|
|
@ -1,382 +0,0 @@
|
|||
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
|
||||
|
||||
|
||||
/* File created by MIDL compiler version 5.01.0164 */
|
||||
/* at Thu Jul 25 15:25:42 2002
|
||||
*/
|
||||
/* Compiler settings for F:\plt\src\mzcom\mzcom.idl:
|
||||
Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext
|
||||
error checks: allocation ref bounds_check enum stub_data
|
||||
*/
|
||||
//@@MIDL_FILE_HEADING( )
|
||||
|
||||
|
||||
/* verify that the <rpcndr.h> version is high enough to compile this file*/
|
||||
#ifndef __REQUIRED_RPCNDR_H_VERSION__
|
||||
#define __REQUIRED_RPCNDR_H_VERSION__ 440
|
||||
#endif
|
||||
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
#ifndef __RPCNDR_H_VERSION__
|
||||
#error this stub requires an updated version of <rpcndr.h>
|
||||
#endif // __RPCNDR_H_VERSION__
|
||||
|
||||
#ifndef COM_NO_WINDOWS_H
|
||||
#include "windows.h"
|
||||
#include "ole2.h"
|
||||
#endif /*COM_NO_WINDOWS_H*/
|
||||
|
||||
#ifndef __mzcom_h__
|
||||
#define __mzcom_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
/* Forward Declarations */
|
||||
|
||||
#ifndef __IMzObj_FWD_DEFINED__
|
||||
#define __IMzObj_FWD_DEFINED__
|
||||
typedef interface IMzObj IMzObj;
|
||||
#endif /* __IMzObj_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef ___IMzObjEvents_FWD_DEFINED__
|
||||
#define ___IMzObjEvents_FWD_DEFINED__
|
||||
typedef interface _IMzObjEvents _IMzObjEvents;
|
||||
#endif /* ___IMzObjEvents_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __MzObj_FWD_DEFINED__
|
||||
#define __MzObj_FWD_DEFINED__
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef class MzObj MzObj;
|
||||
#else
|
||||
typedef struct MzObj MzObj;
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __MzObj_FWD_DEFINED__ */
|
||||
|
||||
|
||||
/* header files for imported files */
|
||||
#include "oaidl.h"
|
||||
#include "ocidl.h"
|
||||
|
||||
void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t);
|
||||
void __RPC_USER MIDL_user_free( void __RPC_FAR * );
|
||||
|
||||
#ifndef __IMzObj_INTERFACE_DEFINED__
|
||||
#define __IMzObj_INTERFACE_DEFINED__
|
||||
|
||||
/* interface IMzObj */
|
||||
/* [unique][helpstring][dual][uuid][object] */
|
||||
|
||||
|
||||
EXTERN_C const IID IID_IMzObj;
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
|
||||
MIDL_INTERFACE("A604CBA8-2AB5-11D4-B6D3-0060089002FE")
|
||||
IMzObj : public IDispatch
|
||||
{
|
||||
public:
|
||||
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Eval(
|
||||
BSTR input,
|
||||
/* [retval][out] */ BSTR __RPC_FAR *output) = 0;
|
||||
|
||||
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE About( void) = 0;
|
||||
|
||||
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Reset( void) = 0;
|
||||
|
||||
};
|
||||
|
||||
#else /* C style interface */
|
||||
|
||||
typedef struct IMzObjVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
|
||||
IMzObj __RPC_FAR * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
|
||||
IMzObj __RPC_FAR * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
|
||||
IMzObj __RPC_FAR * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
|
||||
IMzObj __RPC_FAR * This,
|
||||
/* [out] */ UINT __RPC_FAR *pctinfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
|
||||
IMzObj __RPC_FAR * This,
|
||||
/* [in] */ UINT iTInfo,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
|
||||
IMzObj __RPC_FAR * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
|
||||
/* [in] */ UINT cNames,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
|
||||
IMzObj __RPC_FAR * This,
|
||||
/* [in] */ DISPID dispIdMember,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [in] */ WORD wFlags,
|
||||
/* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
|
||||
/* [out] */ VARIANT __RPC_FAR *pVarResult,
|
||||
/* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
|
||||
/* [out] */ UINT __RPC_FAR *puArgErr);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Eval )(
|
||||
IMzObj __RPC_FAR * This,
|
||||
BSTR input,
|
||||
/* [retval][out] */ BSTR __RPC_FAR *output);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *About )(
|
||||
IMzObj __RPC_FAR * This);
|
||||
|
||||
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Reset )(
|
||||
IMzObj __RPC_FAR * This);
|
||||
|
||||
END_INTERFACE
|
||||
} IMzObjVtbl;
|
||||
|
||||
interface IMzObj
|
||||
{
|
||||
CONST_VTBL struct IMzObjVtbl __RPC_FAR *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef COBJMACROS
|
||||
|
||||
|
||||
#define IMzObj_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define IMzObj_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define IMzObj_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
#define IMzObj_GetTypeInfoCount(This,pctinfo) \
|
||||
(This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
|
||||
|
||||
#define IMzObj_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
|
||||
(This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
|
||||
|
||||
#define IMzObj_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
|
||||
(This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
|
||||
|
||||
#define IMzObj_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
|
||||
(This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
|
||||
|
||||
|
||||
#define IMzObj_Eval(This,input,output) \
|
||||
(This)->lpVtbl -> Eval(This,input,output)
|
||||
|
||||
#define IMzObj_About(This) \
|
||||
(This)->lpVtbl -> About(This)
|
||||
|
||||
#define IMzObj_Reset(This) \
|
||||
(This)->lpVtbl -> Reset(This)
|
||||
|
||||
#endif /* COBJMACROS */
|
||||
|
||||
|
||||
#endif /* C style interface */
|
||||
|
||||
|
||||
|
||||
/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IMzObj_Eval_Proxy(
|
||||
IMzObj __RPC_FAR * This,
|
||||
BSTR input,
|
||||
/* [retval][out] */ BSTR __RPC_FAR *output);
|
||||
|
||||
|
||||
void __RPC_STUB IMzObj_Eval_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IMzObj_About_Proxy(
|
||||
IMzObj __RPC_FAR * This);
|
||||
|
||||
|
||||
void __RPC_STUB IMzObj_About_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IMzObj_Reset_Proxy(
|
||||
IMzObj __RPC_FAR * This);
|
||||
|
||||
|
||||
void __RPC_STUB IMzObj_Reset_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
|
||||
#endif /* __IMzObj_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
|
||||
#ifndef __MZCOMLib_LIBRARY_DEFINED__
|
||||
#define __MZCOMLib_LIBRARY_DEFINED__
|
||||
|
||||
/* library MZCOMLib */
|
||||
/* [helpstring][version][uuid] */
|
||||
|
||||
|
||||
EXTERN_C const IID LIBID_MZCOMLib;
|
||||
|
||||
#ifndef ___IMzObjEvents_DISPINTERFACE_DEFINED__
|
||||
#define ___IMzObjEvents_DISPINTERFACE_DEFINED__
|
||||
|
||||
/* dispinterface _IMzObjEvents */
|
||||
/* [helpstring][uuid] */
|
||||
|
||||
|
||||
EXTERN_C const IID DIID__IMzObjEvents;
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
|
||||
MIDL_INTERFACE("A604CBA9-2AB5-11D4-B6D3-0060089002FE")
|
||||
_IMzObjEvents : public IDispatch
|
||||
{
|
||||
};
|
||||
|
||||
#else /* C style interface */
|
||||
|
||||
typedef struct _IMzObjEventsVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
|
||||
_IMzObjEvents __RPC_FAR * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
|
||||
_IMzObjEvents __RPC_FAR * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
|
||||
_IMzObjEvents __RPC_FAR * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )(
|
||||
_IMzObjEvents __RPC_FAR * This,
|
||||
/* [out] */ UINT __RPC_FAR *pctinfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )(
|
||||
_IMzObjEvents __RPC_FAR * This,
|
||||
/* [in] */ UINT iTInfo,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )(
|
||||
_IMzObjEvents __RPC_FAR * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
|
||||
/* [in] */ UINT cNames,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [size_is][out] */ DISPID __RPC_FAR *rgDispId);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )(
|
||||
_IMzObjEvents __RPC_FAR * This,
|
||||
/* [in] */ DISPID dispIdMember,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [in] */ LCID lcid,
|
||||
/* [in] */ WORD wFlags,
|
||||
/* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
|
||||
/* [out] */ VARIANT __RPC_FAR *pVarResult,
|
||||
/* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
|
||||
/* [out] */ UINT __RPC_FAR *puArgErr);
|
||||
|
||||
END_INTERFACE
|
||||
} _IMzObjEventsVtbl;
|
||||
|
||||
interface _IMzObjEvents
|
||||
{
|
||||
CONST_VTBL struct _IMzObjEventsVtbl __RPC_FAR *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef COBJMACROS
|
||||
|
||||
|
||||
#define _IMzObjEvents_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define _IMzObjEvents_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define _IMzObjEvents_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
#define _IMzObjEvents_GetTypeInfoCount(This,pctinfo) \
|
||||
(This)->lpVtbl -> GetTypeInfoCount(This,pctinfo)
|
||||
|
||||
#define _IMzObjEvents_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
|
||||
(This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo)
|
||||
|
||||
#define _IMzObjEvents_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
|
||||
(This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)
|
||||
|
||||
#define _IMzObjEvents_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
|
||||
(This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr)
|
||||
|
||||
#endif /* COBJMACROS */
|
||||
|
||||
|
||||
#endif /* C style interface */
|
||||
|
||||
|
||||
#endif /* ___IMzObjEvents_DISPINTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
EXTERN_C const CLSID CLSID_MzObj;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
class DECLSPEC_UUID("A3B0AF9E-2AB0-11D4-B6D2-0060089002FE")
|
||||
MzObj;
|
||||
#endif
|
||||
#endif /* __MZCOMLib_LIBRARY_DEFINED__ */
|
||||
|
||||
/* Additional Prototypes for ALL interfaces */
|
||||
|
||||
unsigned long __RPC_USER BSTR_UserSize( unsigned long __RPC_FAR *, unsigned long , BSTR __RPC_FAR * );
|
||||
unsigned char __RPC_FAR * __RPC_USER BSTR_UserMarshal( unsigned long __RPC_FAR *, unsigned char __RPC_FAR *, BSTR __RPC_FAR * );
|
||||
unsigned char __RPC_FAR * __RPC_USER BSTR_UserUnmarshal(unsigned long __RPC_FAR *, unsigned char __RPC_FAR *, BSTR __RPC_FAR * );
|
||||
void __RPC_USER BSTR_UserFree( unsigned long __RPC_FAR *, BSTR __RPC_FAR * );
|
||||
|
||||
/* end of Additional Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Binary file not shown.
|
@ -87,14 +87,6 @@ BEGIN
|
|||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// REGISTRY
|
||||
//
|
||||
|
||||
IDR_MZCOM REGISTRY "MzCOM.rgs"
|
||||
IDR_MZOBJ REGISTRY "MzObj.rgs"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
HKCR
|
||||
{
|
||||
NoRemove AppID
|
||||
{
|
||||
{A604CB9D-2AB5-11D4-B6D3-0060089002FE} = s 'MzCOM'
|
||||
'MzCOM.EXE'
|
||||
{
|
||||
val AppID = s {A604CB9D-2AB5-11D4-B6D3-0060089002FE}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
LIBRARY "MzCOMPS"
|
||||
|
||||
DESCRIPTION 'Proxy/Stub DLL'
|
||||
|
||||
EXPORTS
|
||||
DllGetClassObject @1 PRIVATE
|
||||
DllCanUnloadNow @2 PRIVATE
|
||||
GetProxyDllInfo @3 PRIVATE
|
||||
DllRegisterServer @4 PRIVATE
|
||||
DllUnregisterServer @5 PRIVATE
|
|
@ -1,46 +0,0 @@
|
|||
#lang racket/base
|
||||
|
||||
(define template #<<EOS
|
||||
HKCR
|
||||
{
|
||||
MzCOM.MzObj.@|VERSION| = s 'MzObj Class'
|
||||
{
|
||||
CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}'
|
||||
}
|
||||
MzCOM.MzObj = s 'MzObj Class'
|
||||
{
|
||||
CLSID = s '{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}'
|
||||
CurVer = s 'MzCOM.MzObj.@|VERSION|'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {A3B0AF9E-2AB0-11D4-B6D2-0060089002FE} = s 'MzObj Class'
|
||||
{
|
||||
ProgID = s 'MzCOM.MzObj.@|VERSION|'
|
||||
VersionIndependentProgID = s 'MzCOM.MzObj'
|
||||
ForceRemove 'Programmable'
|
||||
LocalServer32 = s '%MODULE%'
|
||||
val AppID = s '{A604CB9D-2AB5-11D4-B6D3-0060089002FE}'
|
||||
'TypeLib' = s '{A604CB9C-2AB5-11D4-B6D3-0060089002FE}'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EOS
|
||||
)
|
||||
|
||||
(define content (regexp-replace* #rx"@[|]VERSION[|]" template (version)))
|
||||
|
||||
(define file "mzobj.rgs")
|
||||
|
||||
(unless (and (file-exists? file)
|
||||
(equal? content
|
||||
(call-with-input-file*
|
||||
file
|
||||
(lambda (i)
|
||||
(read-string (add1 (string-length content)) i)))))
|
||||
(call-with-output-file*
|
||||
file
|
||||
#:exists 'truncate
|
||||
(lambda (o)
|
||||
(display content o))))
|
Loading…
Reference in New Issue
Block a user