Leaked source code of windows server 2003
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.

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