sccls.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 4k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include "priv.h"
  2. #include "sccls.h"
  3. extern const IClassFactoryVtbl c_CFVtbl;        // forward
  4. //
  5. // This array holds information needed for ClassFactory.
  6. //
  7. // BUGBUG: this table should be ordered in most-to-least used order
  8. //
  9. const OBJECTINFO g_ObjectInfo[] =
  10. {
  11.     
  12.     &c_CFVtbl, &CLSID_ShellAppManager,         CShellAppManager_CreateInstance,
  13.         COCREATEONLY,
  14. #ifndef DOWNLEVEL_PLATFORM
  15.     &c_CFVtbl, &CLSID_DarwinAppPublisher,      CDarwinAppPublisher_CreateInstance,
  16.         COCREATEONLY,
  17. #endif //DOWNLEVEL_PLATFORM
  18.     &c_CFVtbl, &CLSID_EnumInstalledApps,       CEnumInstalledApps_CreateInstance,
  19.         COCREATEONLY, 
  20.     NULL, NULL, NULL, NULL, NULL, 0, 0,0,
  21. } ;
  22. // static class factory (no allocs!)
  23. STDMETHODIMP CClassFactory_QueryInterface(IClassFactory *pcf, REFIID riid, void **ppvObj)
  24. {
  25.     if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown))
  26.     {
  27.         *ppvObj = (void *)pcf;
  28.         DllAddRef();
  29.         return NOERROR;
  30.     }
  31.     *ppvObj = NULL;
  32.     return E_NOINTERFACE;
  33. }
  34. STDMETHODIMP_(ULONG) CClassFactory_AddRef(IClassFactory *pcf)
  35. {
  36.     DllAddRef();
  37.     return 2;
  38. }
  39. STDMETHODIMP_(ULONG) CClassFactory_Release(IClassFactory *pcf)
  40. {
  41.     DllRelease();
  42.     return 1;
  43. }
  44. STDMETHODIMP CClassFactory_CreateInstance(IClassFactory *pcf, IUnknown *punkOuter, REFIID riid, void **ppv)
  45. {
  46.     *ppv = NULL;
  47.     if (punkOuter && !IsEqualIID(riid, &IID_IUnknown))
  48.     {
  49.         // It is technically illegal to aggregate an object and request
  50.         // any interface other than IUnknown. Enforce this.
  51.         //
  52.         return CLASS_E_NOAGGREGATION;
  53.     }
  54.     else
  55.     {
  56.         OBJECTINFO *this = IToClass(OBJECTINFO, cf, pcf);
  57.         IUnknown *punk;
  58.         HRESULT hres;
  59.         
  60.         if (punkOuter) {
  61.             if (!(this->dwClassFactFlags & OIF_ALLOWAGGREGATION))
  62.                 return CLASS_E_NOAGGREGATION;
  63.         }
  64.         // if we're aggregated, then we know we're looking for an
  65.         // IUnknown so we should return punk directly. otherwise
  66.         // we need to QI.
  67.         //
  68.         hres = this->pfnCreateInstance(punkOuter, &punk, this);
  69.         if (SUCCEEDED(hres))
  70.         {
  71.             if (punkOuter)
  72.             {
  73.                 *ppv = (LPVOID)punk;
  74.             }
  75.             else
  76.             {
  77.                 hres = punk->lpVtbl->QueryInterface(punk, riid, ppv);
  78.                 punk->lpVtbl->Release(punk);
  79.             }
  80.         }
  81.     
  82.         ASSERT(FAILED(hres) ? *ppv == NULL : TRUE);
  83.         return hres;
  84.     }
  85. }
  86. STDMETHODIMP CClassFactory_LockServer(IClassFactory *pcf, BOOL fLock)
  87. {
  88.     extern LONG g_cRefThisDll;
  89.     if (fLock)
  90.         DllAddRef();
  91.     else
  92.         DllRelease();
  93.     TraceMsg(DM_TRACE, "sccls: LockServer(%s) to %d", fLock ? TEXT("LOCK") : TEXT("UNLOCK"), g_cRefThisDll);
  94.     return S_OK;
  95. }
  96. const IClassFactoryVtbl c_CFVtbl = {
  97.     CClassFactory_QueryInterface, CClassFactory_AddRef, CClassFactory_Release,
  98.     CClassFactory_CreateInstance,
  99.     CClassFactory_LockServer
  100. };
  101. STDAPI GetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
  102. {
  103.     HRESULT hres = CLASS_E_CLASSNOTAVAILABLE;
  104.     
  105.     extern IClassFactory *CInstClassFactory_Create(const CLSID *pInstID);
  106.     if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown))
  107.     {
  108.         const OBJECTINFO *pcls;
  109.         for (pcls = g_ObjectInfo; pcls->pclsid; pcls++)
  110.         {
  111.             if (IsEqualGUID(rclsid, pcls->pclsid))
  112.             {
  113.                 *ppv = (void *)&(pcls->cf);
  114.                 DllAddRef();        // class factory holds DLL ref count
  115.                 return NOERROR;
  116.             }
  117.         }
  118.     }
  119.     *ppv = NULL;
  120.     return CLASS_E_CLASSNOTAVAILABLE;
  121. }