Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.6 KiB

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