ClassFactory.cpp

00001 
00002 #include <objbase.h>
00003 #include <QApplication>
00004 #include <QUuid>
00005 
00006 #include "ClassFactory.h"
00007 #include "DispatchObject.h"
00008 
00009 /*
00010 ** This totally extremely simple class causes COM to be initialized
00011 **  when our application initializes.
00012 **
00013 */
00014 class UseCOM
00015 {
00016   public:
00017    UseCOM() { ::CoInitialize(NULL); }
00018   ~UseCOM() { ::CoUninitialize();   }
00019 } useCOM;
00020 
00021 HRESULT __stdcall ClassFactory::QueryInterface( const IID & iid, void ** ppv )
00022 {
00023   //
00024   // This is probably totally unnecessary since the Windows COM subsystem
00025   //  called us, and it's totally extremely unlikely that Windows is
00026   //  going to call us and not give us a pointer.  But, check it anyway.
00027   //
00028   //
00029   if( !ppv ) return( E_FAIL );
00030 
00031   //
00032   // Always wipe the callers reference pointer.  This way if we decide
00033   //  there's an error, then we can just return with that error code
00034   //  and not have to also worry about wiping his pointer.  Wiping pointers
00035   //  is a good thing.
00036   //
00037   *ppv = NULL;
00038 
00039   //
00040   // Check the ID requested against known ID numbers for the ClassFactory
00041   //
00042   if( (::IsEqualIID( iid, IID_IUnknown      )) ||
00043       (::IsEqualIID( iid, IID_IClassFactory )) )
00044   {
00045     //
00046     // Set the callers pointer to us.  This may look a little redundant
00047     //  since we are already calling us from a pointer we got for us
00048     //  which is already pointing to us, and we're returning that same
00049     //  pointer, but, hey, this is COM - it's not suppose to make sense!
00050     //
00051     *ppv = (IClassFactory*) this;
00052 
00053 //    qDebug( "ClassFactory::QueryInterface( %s )", qPrintable(QUuid(iid).toString()) );
00054 
00055     //
00056     // Life is good.  Tell the world!
00057     //
00058     return( S_OK );
00059   }
00060 
00061   //
00062   // If the ID requested is not one of the IClassFactory or IUnknown then
00063   //  we don't know what the caller is looking for.
00064   //
00065   return( E_NOINTERFACE );
00066 }
00067 
00068 ULONG __stdcall ClassFactory::AddRef()
00069 {
00070 //  qDebug( "ClassFactory::AddRef" );
00071   return( 1 );
00072 }
00073 
00074 ULONG __stdcall ClassFactory::Release()
00075 {
00076 //  qDebug( "ClassFactory::Release" );
00077   return( 1 );
00078 }
00079 
00080 HRESULT __stdcall ClassFactory::CreateInstance
00081 (
00082   IUnknown * pUnkOuter,
00083   const IID & iid,
00084   void ** ppv
00085 )
00086 {
00087   //
00088   // This is probably totally unnecessary since the Windows COM subsystem
00089   //  called us, and it's totally extremely unlikely that Windows is
00090   //  going to call us and not give us a pointer.  But, check it anyway.
00091   //
00092   //
00093   if( !ppv ) return( E_FAIL );
00094 
00095   //
00096   // Assume an error by clearing the callers handle.  If things
00097   //  work out then ppv will get set to something meaningful.
00098   //
00099   //
00100   *ppv = NULL;
00101 
00102   //
00103   // We are not supporting aggregation (yet) so return
00104   //  the appropriate error code.
00105   //
00106   //
00107   if( pUnkOuter )
00108     return( CLASS_E_NOAGGREGATION );
00109 
00110 //  qDebug( "ClassFactory::CreateInstance( %s )", qPrintable(QUuid(iid).toString()) );
00111 
00112   //
00113   // Create a new COM object. Note that the object reference count
00114   //  is now 1.
00115   //
00116   DispatchObject * object = new DispatchObject();
00117 
00118   //
00119   // Query the COM object to see if it supports the
00120   //  requested interface.
00121   //
00122   HRESULT hr = object-> QueryInterface( iid, ppv );
00123 
00124   //
00125   // Release the reference *we* have.  If the QueryInterface call
00126   //  was successful then there should have been one added to the
00127   //  reference count.  If not, the object we created will be
00128   //  destroyed here.
00129   //
00130   object-> Release();
00131 
00132   //
00133   // We should have returned above with no error, so if we
00134   //  got down here then return thusly.
00135   //
00136   //
00137   return( hr );
00138 }
00139 
00140 HRESULT __stdcall ClassFactory::LockServer( BOOL lock )
00141 {
00142 //  qDebug( "ClassFactory::LockServer %s", lock? "True":"False" );
00143   if( lock ) ::InterlockedIncrement( &s_serverLocks );
00144   else       ::InterlockedDecrement( &s_serverLocks );
00145   return NOERROR;
00146 }
00147 
00148 ClassFactory::ClassFactory( const QUuid & clsid )
00149 {
00150   HRESULT hr = ::CoRegisterClassObject
00151   (
00152     clsid,
00153     static_cast<IClassFactory*>(this),
00154     CLSCTX_LOCAL_SERVER,
00155     REGCLS_MULTIPLEUSE,
00156     &dwRegister
00157   );
00158 
00159   if( FAILED(hr) )
00160   {
00161     qDebug( "ClassFactory: failed to register class object" );
00162   }
00163 }
00164 
00165 ClassFactory::~ClassFactory()
00166 {
00167   ::CoRevokeClassObject( dwRegister );
00168 }
00169 
00170 LONG ClassFactory::s_serverLocks = 0;
00171 




~ ~ ~ ~ ~ ~
Don't create Texas sized problems...
Comment your Code!
~ ~ ~ ~ ~ ~
Author: Mark Petryk
Lorimark Solutions, LLC