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.

130 lines
3.4 KiB

  1. #include "cabinet.h"
  2. ///////////////////////////////////////////////////////////////////////////////////////
  3. //
  4. // class factory for explorer.exe
  5. //
  6. // These objects do not exist in the registry but rather are registered dynamically at
  7. // runtime. Since ClassFactory_Start is called on the the tray's thread, all objects
  8. // will be registered on that thread.
  9. //
  10. ///////////////////////////////////////////////////////////////////////////////////////
  11. typedef HRESULT (*LPFNCREATEOBJINSTANCE)(IUnknown* pUnkOuter, IUnknown** ppunk);
  12. class CDynamicClassFactory : public IClassFactory
  13. {
  14. public:
  15. // *** IUnknown ***
  16. STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
  17. {
  18. static const QITAB qit[] =
  19. {
  20. QITABENT(CDynamicClassFactory, IClassFactory),
  21. { 0 },
  22. };
  23. return QISearch(this, qit, riid, ppv);
  24. }
  25. STDMETHODIMP_(ULONG) AddRef() { return ++_cRef; }
  26. STDMETHODIMP_(ULONG) Release()
  27. {
  28. if (--_cRef > 0)
  29. {
  30. return _cRef;
  31. }
  32. delete this;
  33. return 0;
  34. }
  35. // *** IClassFactory ***
  36. STDMETHODIMP CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv)
  37. {
  38. *ppv = NULL;
  39. IUnknown *punk;
  40. HRESULT hr = _pfnCreate(punkOuter, &punk);
  41. if (SUCCEEDED(hr))
  42. {
  43. hr = punk->QueryInterface(riid, ppv);
  44. punk->Release();
  45. }
  46. return hr;
  47. }
  48. STDMETHODIMP LockServer(BOOL) { return S_OK; }
  49. // *** misc public methods ***
  50. HRESULT Register()
  51. {
  52. return CoRegisterClassObject(*_pclsid, this, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
  53. REGCLS_MULTIPLEUSE, &_dwClassObject);
  54. }
  55. HRESULT Revoke()
  56. {
  57. HRESULT hr = CoRevokeClassObject(_dwClassObject);
  58. _dwClassObject = 0;
  59. return hr;
  60. }
  61. CDynamicClassFactory(CLSID const* pclsid, LPFNCREATEOBJINSTANCE pfnCreate) : _pclsid(pclsid),
  62. _pfnCreate(pfnCreate), _cRef(1) {}
  63. private:
  64. CLSID const* _pclsid;
  65. LPFNCREATEOBJINSTANCE _pfnCreate;
  66. DWORD _dwClassObject;
  67. ULONG _cRef;
  68. };
  69. HRESULT CTaskBand_CreateInstance(IUnknown* punkOuter, IUnknown** ppunk);
  70. HRESULT CTrayBandSiteService_CreateInstance(IUnknown* punkOuter, IUnknown** ppunk);
  71. HRESULT CTrayNotifyStub_CreateInstance(IUnknown* punkOuter, IUnknown** ppunk);
  72. static const struct
  73. {
  74. CLSID const* pclsid;
  75. LPFNCREATEOBJINSTANCE pfnCreate;
  76. }
  77. c_ClassParams[] =
  78. {
  79. { &CLSID_TaskBand, CTaskBand_CreateInstance },
  80. { &CLSID_TrayBandSiteService, CTrayBandSiteService_CreateInstance },
  81. { &CLSID_TrayNotify, CTrayNotifyStub_CreateInstance },
  82. };
  83. CDynamicClassFactory* g_rgpcf[ARRAYSIZE(c_ClassParams)] = {0};
  84. void ClassFactory_Start()
  85. {
  86. for (int i = 0; i < ARRAYSIZE(c_ClassParams); i++)
  87. {
  88. g_rgpcf[i] = new CDynamicClassFactory(c_ClassParams[i].pclsid, c_ClassParams[i].pfnCreate);
  89. if (g_rgpcf[i])
  90. {
  91. g_rgpcf[i]->Register();
  92. }
  93. }
  94. }
  95. void ClassFactory_Stop()
  96. {
  97. for (int i = 0; i < ARRAYSIZE(c_ClassParams); i++)
  98. {
  99. if (g_rgpcf[i])
  100. {
  101. g_rgpcf[i]->Revoke();
  102. g_rgpcf[i]->Release();
  103. g_rgpcf[i] = NULL;
  104. }
  105. }
  106. }