GME  13
Core.cpp
Go to the documentation of this file.
00001 // Core.cpp : Implementation of DLL Exports.
00002 
00003 
00004 // Note: Proxy/Stub Information
00005 //      To merge the proxy/stub code into the object DLL, add the file 
00006 //      dlldatax.c to the project.  Make sure precompiled headers 
00007 //      are turned off for this file, and add _MERGE_PROXYSTUB to the 
00008 //      defines for the project.  
00009 //
00010 //      If you are not running WinNT4.0 or Win95 with DCOM, then you
00011 //      need to remove the following define from dlldatax.c
00012 //      #define _WIN32_WINNT 0x0400
00013 //
00014 //      Further, if you are running MIDL without /Oicf switch, you also 
00015 //      need to remove the following define from dlldatax.c.
00016 //      #define USE_STUBLESS_PROXY
00017 //
00018 //      Modify the custom build rule for Core.idl by adding the following 
00019 //      files to the Outputs.
00020 //          Core_p.c
00021 //          dlldata.c
00022 //      To build a separate proxy/stub DLL, 
00023 //      run nmake -f Coreps.mk in the project directory.
00024 
00025 #include "stdafx.h"
00026 #include "resource.h"
00027 
00028 #include "CommonError.h"
00029 #include "CommonSmart.h"
00030 
00031 #include "CoreProject.h"
00032 #include "CoreBinFile.h"
00033 #include "CoreMetaProject.h"
00034 
00035 #import "CoreLib.tlb" implementation_only no_namespace raw_method_prefix("") high_method_prefix("__") no_registry
00036 
00037 #ifdef _MERGE_PROXYSTUB
00038 extern "C" HINSTANCE hProxyDll;
00039 #endif
00040 
00041 CComModule _Module;
00042 
00043 class CCoreCollectionHandler;
00044 
00045 class CCoreCollectionHandlerTearOff : public ICoreMetaObjects
00046 {
00047         friend class CCoreCollectionHandler;
00048         long refcount;
00049         CComPtr<ICoreMetaObjects> m_pInner;
00050         CComPtr<CCoreCollectionHandler> m_pHandler;
00051 
00052     public:
00053                 CCoreCollectionHandlerTearOff() : refcount(1) {}
00054 
00055                 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject);
00056 
00057         virtual ULONG STDMETHODCALLTYPE AddRef(void)
00058                 {
00059                         return InterlockedIncrement(&refcount);
00060                 }
00061 
00062         virtual ULONG STDMETHODCALLTYPE Release(void)
00063                 {
00064                         long refcount = InterlockedDecrement(&refcount);
00065                         if (refcount == 0)
00066                                 delete this;
00067                         return refcount;
00068                 }
00069 
00070                 // standard marshaller does not marshal array of interface pointers
00071                 virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetAll(/* [in] */ long count, /* [size_is][out] */ ICoreMetaObject **p)
00072                 {
00073                         for (long i = 0; i < count; i++)
00074                         {
00075                                 ICoreMetaObject* o = nullptr;
00076                                 HRESULT hr = get_Item(i+1, &o); // get_Item has 1-based index
00077                                 if (FAILED(hr))
00078                                 {
00079                                         for (i--; i >= 0; i--)
00080                                         {
00081                                                 (*(p + i))->Release();
00082                                                 (*(p + i)) = nullptr;
00083                                         }
00084                                         return hr;
00085                                 }
00086                                 (*(p + i)) = o;
00087                         }
00088                         return S_OK;
00089                 }
00090 
00091                 // Rest of this class delegates calls to m_pInner
00092 
00093                 virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(__RPC__out UINT *pctinfo)
00094                 {
00095                         return m_pInner->GetTypeInfoCount(pctinfo);
00096                 }
00097         
00098         virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(/* [in] */ UINT iTInfo, /* [in] */ LCID lcid, /* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo)
00099                 {
00100                         return m_pInner->GetTypeInfo(iTInfo, lcid, ppTInfo);
00101                 }
00102         
00103         virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(/* [in] */ __RPC__in REFIID riid, /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
00104             /* [range][in] */ __RPC__in_range(0,16384) UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId)
00105                 {
00106                         return m_pInner->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId);
00107                 }
00108         
00109         virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(/* [in] */ DISPID dispIdMember, /* [in] */ REFIID riid, /* [in] */ LCID lcid,
00110             /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS *pDispParams, /* [out] */ VARIANT *pVarResult, /* [out] */ EXCEPINFO *pExcepInfo,
00111             /* [out] */ UINT *puArgErr)
00112                 {
00113                         return m_pInner->Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
00114                 }
00115 
00116                 virtual HRESULT STDMETHODCALLTYPE get_Count(/* [retval][out] */ long *p)
00117                 {
00118                         return m_pInner->get_Count(p);
00119                 }
00120         
00121         virtual HRESULT STDMETHODCALLTYPE get_Item(/* [in] */ long n, /* [retval][out] */ ICoreMetaObject **p)
00122                 {
00123                         return m_pInner->get_Item(n, p);
00124                 }
00125         
00126         virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(/* [retval][out] */ IUnknown **p)
00127                 {
00128                         return m_pInner->get__NewEnum(p);
00129                 }
00130 
00131                 virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Insert(/* [in] */ ICoreMetaObject *p, /* [in] */ long at)
00132                 {
00133                         return m_pInner->Insert(p, at);
00134                 }
00135 
00136                 virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Append(/* [in] */ ICoreMetaObject *p)
00137                 {
00138                         return m_pInner->Append(p);
00139                 }
00140         
00141         virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Find(/* [in] */ ICoreMetaObject *p, /* [in] */ long start, /* [retval][out] */ long *res)
00142                 {
00143                         return m_pInner->Find(p, start, res);
00144                 }
00145         
00146         virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Remove(/* [in] */ long n)
00147                 {
00148                         return m_pInner->Remove(n);
00149                 }
00150 };
00151 
00152 
00153 class CCoreCollectionHandler : 
00154         public CComObjectRootEx<CComMultiThreadModel>,
00155         public CComCoClass<CCoreCollectionHandler, &__uuidof(CoreCollectionHandler)>,
00156         public IUnknown
00157 {
00158 
00159         DECLARE_GET_CONTROLLING_UNKNOWN()
00160 
00161         DECLARE_REGISTRY_RESOURCEID(IDR_CORECOLLECTIONHANDLER)
00162 
00163         CComPtr<IUnknown> m_pUnknownInner;
00164         HRESULT FinalConstruct()
00165         {
00166                 HRESULT hr = CoGetStdMarshalEx(m_pOuterUnknown, SMEXF_HANDLER, &m_pUnknownInner);
00167                 return hr;
00168         }
00169 
00170         static HRESULT WINAPI QI(void* pv, REFIID riid, LPVOID* ppv, DWORD_PTR dw)
00171         {
00172                 CCoreCollectionHandler* _this = (CCoreCollectionHandler*)pv;
00173                 return _this->QI(riid, ppv, dw);
00174         }
00175 
00176         HRESULT WINAPI QI(REFIID riid, LPVOID* ppv, DWORD_PTR dw)
00177         {
00178                 if (ppv == NULL)
00179                         return E_POINTER;
00180         
00181                 static const ::GUID guids[] = {
00182 //def lit(id): return "{%s, %s, %s, {%s, %s, %s}}" % ( hex(id.time_low), hex(id.time_mid), hex(id.time_hi_version), hex(id.clock_seq_hi_variant), hex(id.clock_seq_low), ', '.join((hex(ord(b)) for b in id.bytes[10:])))
00183 //print "\n".join(["%s, // %ss %s" % (lit(l[0]), l[1], l[0]) for l in ids])
00184 {0xc5aac2f0L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaObjects c5aac2f0-c1fd-11d3-9ad2-00aa00b6fe26           
00185 {0xc59c2210L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaFolders c59c2210-c1fd-11d3-9ad2-00aa00b6fe26
00186 {0xc5f4c2f0L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaFCOs c5f4c2f0-c1fd-11d3-9ad2-00aa00b6fe26
00187 {0xc6f3f340L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaAttributes c6f3f340-c1fd-11d3-9ad2-00aa00b6fe26
00188 {0xc71a26f0L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaParts c71a26f0-c1fd-11d3-9ad2-00aa00b6fe26
00189 {0xc7f19c60L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaConnPoints c7f19c60-c1fd-11d3-9ad2-00aa00b6fe26
00190 {0xc79f1840L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaRegNodes c79f1840-c1fd-11d3-9ad2-00aa00b6fe26
00191 {0xc66a6c60L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaMetaFCOs c66a6c60-c1fd-11d3-9ad2-00aa00b6fe26
00192 {0x43d12111L, 0x12caL, 0x11d3L, {0xa6L, 0xecL, 0x0, 0x60, 0x8, 0x2d, 0xf8, 0x84}}, // CoreMetaObjects 43d12111-12ca-11d3-a6ec-0060082df884
00193 {0x43d12127L, 0x12caL, 0x11d3L, {0xa6L, 0xecL, 0x0, 0x60, 0x8, 0x2d, 0xf8, 0x84}}, // CoreMetaAttributes 43d12127-12ca-11d3-a6ec-0060082df884
00194 {0x43d12111L, 0x22caL, 0x11d3L, {0xa6L, 0xecL, 0x0, 0x60, 0x8, 0x2d, 0xf8, 0x84}}, // CoreObjects 43d12111-22ca-11d3-a6ec-0060082df884
00195 {0x43d12127L, 0x22caL, 0x11d3L, {0xa6L, 0xecL, 0x0, 0x60, 0x8, 0x2d, 0xf8, 0x84}}, // CoreAttributes 43d12127-22ca-11d3-a6ec-0060082df884
00196 {0xc61352b0L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaMetaAspects c61352b0-c1fd-11d3-9ad2-00aa00b6fe26
00197 {0xc851e130L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaMetaRoles c851e130-c1fd-11d3-9ad2-00aa00b6fe26
00198 {0xc6922740L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaMetaAttributes c6922740-c1fd-11d3-9ad2-00aa00b6fe26
00199 {0xc6b85af0L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaMetaFolders c6b85af0-c1fd-11d3-9ad2-00aa00b6fe26
00200 {0xc761f8c0L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaMetaPointerSpecs c761f8c0-c1fd-11d3-9ad2-00aa00b6fe26
00201 {0xc795ed20L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x27}}, // MgaMetaRegNodes c795ed20-c1fd-11d3-9ad2-00aa00b6fe27
00202 {0xc8ec3720L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaConstraints c8ec3720-c1fd-11d3-9ad2-00aa00b6fe26
00203 {0xc8ec3720L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x27}}, // MgaMetaParts c8ec3720-c1fd-11d3-9ad2-00aa00b6fe27
00204 {0xc8ec3723L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x27}}, // MgaMetaModels c8ec3723-c1fd-11d3-9ad2-00aa00b6fe27
00205 {0xc8432623L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x27}}, // MgaMetaConnJoints c8432623-c1fd-11d3-9ad2-00aa00b6fe27
00206 {0xc8124623L, 0xc51dL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x27}}, // MgaMetaPointerItems c8124623-c51d-11d3-9ad2-00aa00b6fe27
00207 {0xc8124623L, 0xc51dL, 0x1ad3L, {0x9aL, 0xd2L, 0x11, 0xaa, 0x1, 0x76, 0xfe, 0x27}}, // MgaMetaEnumItems c8124623-c51d-1ad3-9ad2-11aa0176fe27
00208 {0xc8a5ec80L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaAddOns c8a5ec80-c1fd-11d3-9ad2-00aa00b6fe26
00209 {0xc87caa70L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // IMgaTerritorys c87caa70-c1fd-11d3-9ad2-00aa00b6fe26
00210 {0xc8cda760L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaComponents c8cda760-c1fd-11d3-9ad2-00aa00b6fe26
00211 {0xc9d8df93L, 0xc1fdL, 0x11d3L, {0x9aL, 0xd2L, 0x0, 0xaa, 0x0, 0xb6, 0xfe, 0x26}}, // MgaClients c9d8df93-c1fd-11d3-9ad2-00aa00b6fe26
00212                 };
00213 
00214                 bool match = false;
00215                 if (riid != __uuidof(IDispatch)) // microoptimization
00216                 {
00217                         for (int i = 0; i < sizeof(guids) / sizeof(guids[0]); i++)
00218                         {
00219                                 if (guids[i] == riid)
00220                                 {
00221                                         match = true;
00222                                         break;
00223                                 }
00224                         }
00225                 }
00226                 HRESULT hr;
00227                 CComPtr<ICoreMetaObjects> pCollection;
00228                 if (FAILED(hr = m_pUnknownInner->QueryInterface(riid, (void**)&pCollection)))
00229                         return hr;
00230                 if (!match)
00231                 {
00232                         *ppv = pCollection.Detach();
00233                         return S_OK;
00234                 }
00235                 CCoreCollectionHandlerTearOff* tearoff = new CCoreCollectionHandlerTearOff(); // refcount == 1
00236                 // We know that all the IMgaXXXs have the same vtable, so this works
00237                 tearoff->m_pInner = pCollection;
00238                 tearoff->m_pHandler = this;
00239                 *ppv = (ICoreMetaObjects*)tearoff;
00240                 return S_OK;
00241         }
00242 
00243 BEGIN_COM_MAP(CCoreCollectionHandler)
00244         COM_INTERFACE_ENTRY(IUnknown)
00245         COM_INTERFACE_ENTRY_FUNC_BLIND(0, QI)
00246 END_COM_MAP()
00247 
00248 };
00249 
00250 HRESULT STDMETHODCALLTYPE CCoreCollectionHandlerTearOff::QueryInterface(REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
00251 {
00252         return this->m_pHandler->QueryInterface(riid, ppvObject);
00253 }
00254 
00255 BEGIN_OBJECT_MAP(ObjectMap)
00256 OBJECT_ENTRY(__uuidof(CoreProject), CCoreProject)
00257 OBJECT_ENTRY(__uuidof(CoreBinFile), CCoreBinFile)
00258 OBJECT_ENTRY(__uuidof(CoreMetaProject), CCoreMetaProject)
00259 OBJECT_ENTRY(__uuidof(CoreCollectionHandler), CCoreCollectionHandler)
00260 END_OBJECT_MAP()
00261 
00263 // DLL Entry Point
00264 
00265 extern "C"
00266 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
00267 {
00268     lpReserved;
00269 #ifdef _MERGE_PROXYSTUB
00270     if (!PrxDllMain(hInstance, dwReason, lpReserved))
00271         return FALSE;
00272 #endif
00273     if (dwReason == DLL_PROCESS_ATTACH)
00274     {
00275         _Module.Init(ObjectMap, hInstance, &LIBID_MGACoreLib);
00276         DisableThreadLibraryCalls(hInstance);
00277     }
00278     else if (dwReason == DLL_PROCESS_DETACH)
00279         _Module.Term();
00280     return TRUE;    // ok
00281 }
00282 
00284 // Used to determine whether the DLL can be unloaded by OLE
00285 
00286 STDAPI DllCanUnloadNow(void)
00287 {
00288 #ifdef _MERGE_PROXYSTUB
00289     if (PrxDllCanUnloadNow() != S_OK)
00290         return S_FALSE;
00291 #endif
00292     return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
00293 }
00294 
00296 // Returns a class factory to create an object of the requested type
00297 
00298 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
00299 {
00300 #ifdef _MERGE_PROXYSTUB
00301     if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
00302         return S_OK;
00303 #endif
00304     return _Module.GetClassObject(rclsid, riid, ppv);
00305 }
00306 
00308 // DllRegisterServer - Adds entries to the system registry
00309 
00310 STDAPI DllRegisterServer(void)
00311 {
00312 #ifdef _MERGE_PROXYSTUB
00313     HRESULT hRes = PrxDllRegisterServer();
00314     if (FAILED(hRes))
00315         return hRes;
00316 #endif
00317     // registers object, typelib and all interfaces in typelib
00318     return _Module.RegisterServer(TRUE);
00319 }
00320 
00322 // DllUnregisterServer - Removes entries from the system registry
00323 
00324 STDAPI DllUnregisterServer(void)
00325 {
00326 #ifdef _MERGE_PROXYSTUB
00327     PrxDllUnregisterServer();
00328 #endif
00329     return _Module.UnregisterServer(TRUE);
00330 }
00331 
00332 HRESULT check_location_compatibility(ICoreMetaObject *newobj, ICoreMetaObject *oldobj) {
00333         CComPtr<ICoreMetaProject> proj1, proj2;
00334         COMTRY {
00335                 if(!oldobj) {
00336                         COMTHROW(newobj->get_Project(&proj1));
00337                         //instead of proj1->get_Name
00338                         if( &CCoreMetaProject::get_Name != &ICoreMetaProject::get_Name) return E_SAMEPROJECT;
00339                 }
00340                 else {
00341                         COMTHROW(oldobj->get_Project(&proj2));
00342                         if(proj1 != proj2) return E_SAMEPROJECT;
00343                 }
00344         }
00345         COMCATCH(;)
00346         
00347 }
00348 
00349 HRESULT check_location_compatibility(ICoreMetaAttribute *newobj, ICoreMetaAttribute *oldobj) {
00350         CComPtr<ICoreMetaObject> oldo, newo;
00351         COMTRY {
00352                 COMTHROW(newobj->get_Object(&newo));
00353                 if(oldobj) COMTHROW(oldobj->get_Object(&oldo));
00354                 COMTHROW(check_location_compatibility(newo, oldo));
00355         }
00356         COMCATCH(;)
00357 }
00358 
00359 HRESULT check_location_compatibility(ICoreObject *newobj, ICoreObject *oldobj) {
00360         CComPtr<ICoreProject> proj1, proj2;
00361         COMTRY {
00362                 if(!oldobj) {
00363                         COMTHROW(newobj->get_Project(&proj1));
00364                         //instead of proj1->OpenProject
00365                         if( &CCoreProject::OpenProject != &ICoreProject::OpenProject) return E_SAMEPROJECT;
00366                 }
00367                 else {
00368                         COMTHROW(oldobj->get_Project(&proj2));
00369                         if(proj1 != proj2) return E_SAMEPROJECT;
00370                 }
00371         }
00372         COMCATCH(;)
00373         
00374 }
00375 
00376 HRESULT check_location_compatibility(ICoreAttribute *newobj, ICoreAttribute *oldobj) {
00377         CComPtr<ICoreObject> oldo, newo;
00378         COMTRY {
00379                 COMTHROW(newobj->get_Object(&newo));
00380                 if(oldobj) COMTHROW(oldobj->get_Object(&oldo));
00381                 COMTHROW(check_location_compatibility(newo, oldo));
00382         }
00383         COMCATCH(;)
00384 }
00385 
00386 #ifdef _ATL_DEBUG_INTERFACES
00387 bool IsQIThunk(IUnknown *p) {
00388         // Is p a thunk?
00389         // dynamic_cast can't work, since ATL::_QIThunk has no superclass (not even IUnknown)
00390         //  solution: compare virtual function tables
00391         ATL::_QIThunk dummy((IUnknown*)(void*)1, L"dummy", IID_IUnknown, 0, false);
00392 
00393         return *((int**)(void*)p) == *((int**)(void*)&dummy);
00394 }
00395 #endif