From dfeba12997e7262bf5f5b8c7b6eb06d9018545de Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 20 May 2014 18:01:17 +0100 Subject: [PATCH] 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). --- racket/src/mzcom/com_glue.c | 704 ++++++++++++++++++++++++++ racket/src/mzcom/com_glue.h | 75 +++ racket/src/mzcom/mzcom.cxx | 299 ++++++----- racket/src/mzcom/mzobj.cxx | 48 +- racket/src/mzcom/mzobj.h | 33 +- racket/src/mzcom/stdafx.h | 38 -- racket/src/worksp/README | 23 +- racket/src/worksp/mzcom/MzCOM.vcproj | 64 +-- racket/src/worksp/mzcom/MzCOMCP.h | 32 -- racket/src/worksp/mzcom/README | 2 - racket/src/worksp/mzcom/mzcom.def | 9 - racket/src/worksp/mzcom/mzcom.h | 382 -------------- racket/src/worksp/mzcom/mzcom.opt | Bin 65536 -> 0 bytes racket/src/worksp/mzcom/mzcom.rc | 8 - racket/src/worksp/mzcom/mzcom.rgs | 11 - racket/src/worksp/mzcom/mzcomps.def | 11 - racket/src/worksp/mzcom/mzobj_rgs.rkt | 46 -- 17 files changed, 1032 insertions(+), 753 deletions(-) create mode 100644 racket/src/mzcom/com_glue.c create mode 100644 racket/src/mzcom/com_glue.h delete mode 100644 racket/src/mzcom/stdafx.h delete mode 100644 racket/src/worksp/mzcom/MzCOMCP.h delete mode 100644 racket/src/worksp/mzcom/mzcom.def delete mode 100644 racket/src/worksp/mzcom/mzcom.h delete mode 100644 racket/src/worksp/mzcom/mzcom.opt delete mode 100644 racket/src/worksp/mzcom/mzcom.rgs delete mode 100644 racket/src/worksp/mzcom/mzcomps.def delete mode 100644 racket/src/worksp/mzcom/mzobj_rgs.rkt diff --git a/racket/src/mzcom/com_glue.c b/racket/src/mzcom/com_glue.c new file mode 100644 index 0000000000..48a9f0e0ac --- /dev/null +++ b/racket/src/mzcom/com_glue.c @@ -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 +#include +#include +#include +#include +#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; +} diff --git a/racket/src/mzcom/com_glue.h b/racket/src/mzcom/com_glue.h new file mode 100644 index 0000000000..bceb397723 --- /dev/null +++ b/racket/src/mzcom/com_glue.h @@ -0,0 +1,75 @@ +#ifndef _COM_GLUE_H_ +#define _COM_GLUE_H_ + +#ifdef FOR_GLUE + +#include + +// {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_ diff --git a/racket/src/mzcom/mzcom.cxx b/racket/src/mzcom/mzcom.cxx index 3f54c643d2..263dd64f18 100644 --- a/racket/src/mzcom/mzcom.cxx +++ b/racket/src/mzcom/mzcom.cxx @@ -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 -#include "mzcom.h" -#include "mzcom_i.c" -#include "mzobj.h" +#include +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; } diff --git a/racket/src/mzcom/mzobj.cxx b/racket/src/mzcom/mzobj.cxx index c85fd1172e..96d7bb45b8 100644 --- a/racket/src/mzcom/mzobj.cxx +++ b/racket/src/mzcom/mzobj.cxx @@ -12,10 +12,14 @@ START_XFORM_SKIP; #endif -#include "stdafx.h" #include "resource.h" -#include "mzcom.h" +#include + +#include +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 diff --git a/racket/src/mzcom/mzobj.h b/racket/src/mzcom/mzobj.h index 5d99f57ebd..b0794f60b7 100644 --- a/racket/src/mzcom/mzobj.h +++ b/racket/src/mzcom/mzobj.h @@ -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, - public CComCoClass, - public IConnectionPointContainerImpl, - public IDispatchImpl, - 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 diff --git a/racket/src/mzcom/stdafx.h b/racket/src/mzcom/stdafx.h deleted file mode 100644 index 77990381cd..0000000000 --- a/racket/src/mzcom/stdafx.h +++ /dev/null @@ -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 -//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 - -//{{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) diff --git a/racket/src/worksp/README b/racket/src/worksp/README index 468b06db53..3e454f7bab 100644 --- a/racket/src/worksp/README +++ b/racket/src/worksp/README @@ -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 diff --git a/racket/src/worksp/mzcom/MzCOM.vcproj b/racket/src/worksp/mzcom/MzCOM.vcproj index 5fbb4347c6..d91f0b0c03 100644 --- a/racket/src/worksp/mzcom/MzCOM.vcproj +++ b/racket/src/worksp/mzcom/MzCOM.vcproj @@ -24,14 +24,9 @@ ConfigurationType="1" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" - UseOfATL="1" ATLMinimizesCRunTimeLibraryUsage="false" CharacterSet="2" > - @@ -75,14 +71,9 @@ ConfigurationType="1" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" - UseOfATL="1" ATLMinimizesCRunTimeLibraryUsage="false" CharacterSet="2" > - - @@ -183,14 +171,9 @@ ConfigurationType="1" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" - UseOfATL="1" ATLMinimizesCRunTimeLibraryUsage="false" CharacterSet="2" > - - @@ -296,14 +276,9 @@ ConfigurationType="1" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" - UseOfATL="1" ATLMinimizesCRunTimeLibraryUsage="false" CharacterSet="2" > - + + @@ -367,27 +347,19 @@ RelativePath="..\..\mzcom\mzobj.cxx" > - - - - - - + + - - - - diff --git a/racket/src/worksp/mzcom/MzCOMCP.h b/racket/src/worksp/mzcom/MzCOMCP.h deleted file mode 100644 index 042f472f9b..0000000000 --- a/racket/src/worksp/mzcom/MzCOMCP.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _MZCOMCP_H_ -#define _MZCOMCP_H_ - -template -class CProxy_IMzObjEvents : public IConnectionPointImpl -{ - //Warning this class may be recreated by the wizard. -public: - VOID Fire_SchemeError(BSTR description) - { - T* pT = static_cast(this); - int nConnectionIndex; - CComVariant* pvars = new CComVariant[1]; - int nConnections = m_vec.GetSize(); - - for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++) - { - pT->Lock(); - CComPtr sp = m_vec.GetAt(nConnectionIndex); - pT->Unlock(); - IDispatch* pDispatch = reinterpret_cast(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 diff --git a/racket/src/worksp/mzcom/README b/racket/src/worksp/mzcom/README index a4f3af9418..93178ad406 100644 --- a/racket/src/worksp/mzcom/README +++ b/racket/src/worksp/mzcom/README @@ -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. diff --git a/racket/src/worksp/mzcom/mzcom.def b/racket/src/worksp/mzcom/mzcom.def deleted file mode 100644 index 73c59f3c5e..0000000000 --- a/racket/src/worksp/mzcom/mzcom.def +++ /dev/null @@ -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 diff --git a/racket/src/worksp/mzcom/mzcom.h b/racket/src/worksp/mzcom/mzcom.h deleted file mode 100644 index b172250ba4..0000000000 --- a/racket/src/worksp/mzcom/mzcom.h +++ /dev/null @@ -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 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 -#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 diff --git a/racket/src/worksp/mzcom/mzcom.opt b/racket/src/worksp/mzcom/mzcom.opt deleted file mode 100644 index b2d3b3eb9ab141b02aaf6c92576ec2444eb080c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65536 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 diff --git a/racket/src/worksp/mzcom/mzcom.rc b/racket/src/worksp/mzcom/mzcom.rc index 2f872fc145..b69b531450 100644 --- a/racket/src/worksp/mzcom/mzcom.rc +++ b/racket/src/worksp/mzcom/mzcom.rc @@ -87,14 +87,6 @@ BEGIN END -///////////////////////////////////////////////////////////////////////////// -// -// REGISTRY -// - -IDR_MZCOM REGISTRY "MzCOM.rgs" -IDR_MZOBJ REGISTRY "MzObj.rgs" - ///////////////////////////////////////////////////////////////////////////// // // Dialog diff --git a/racket/src/worksp/mzcom/mzcom.rgs b/racket/src/worksp/mzcom/mzcom.rgs deleted file mode 100644 index 3c0e1478f1..0000000000 --- a/racket/src/worksp/mzcom/mzcom.rgs +++ /dev/null @@ -1,11 +0,0 @@ -HKCR -{ - NoRemove AppID - { - {A604CB9D-2AB5-11D4-B6D3-0060089002FE} = s 'MzCOM' - 'MzCOM.EXE' - { - val AppID = s {A604CB9D-2AB5-11D4-B6D3-0060089002FE} - } - } -} diff --git a/racket/src/worksp/mzcom/mzcomps.def b/racket/src/worksp/mzcom/mzcomps.def deleted file mode 100644 index 89ff942b13..0000000000 --- a/racket/src/worksp/mzcom/mzcomps.def +++ /dev/null @@ -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 diff --git a/racket/src/worksp/mzcom/mzobj_rgs.rkt b/racket/src/worksp/mzcom/mzobj_rgs.rkt deleted file mode 100644 index 0d5a7f7216..0000000000 --- a/racket/src/worksp/mzcom/mzobj_rgs.rkt +++ /dev/null @@ -1,46 +0,0 @@ -#lang racket/base - -(define template #<