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.

164 lines
3.4 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #define INITGUID
  4. #include <initguid.h>
  5. #include "iids.h"
  6. #define DECL_CRTFREE
  7. #include <crtfree.h>
  8. HINSTANCE g_hInstance = NULL;
  9. LONG g_cRef = 0;
  10. EXTERN_C BOOL DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID pReserved)
  11. {
  12. switch ( dwReason )
  13. {
  14. case DLL_PROCESS_ATTACH:
  15. ClassCache_Init();
  16. TraceSetMaskFromCLSID(CLSID_DsPropertyPages);
  17. g_hInstance = hInstance;
  18. break;
  19. case DLL_PROCESS_DETACH:
  20. ClassCache_Discard();
  21. break;
  22. }
  23. return TRUE;
  24. }
  25. // lifetime
  26. STDAPI_(void) DllAddRef()
  27. {
  28. InterlockedIncrement(&g_cRef);
  29. }
  30. STDAPI_(void) DllRelease()
  31. {
  32. InterlockedDecrement(&g_cRef);
  33. }
  34. STDAPI DllCanUnloadNow(VOID)
  35. {
  36. return (g_cRef > 0) ? S_FALSE : S_OK;
  37. }
  38. // class factory
  39. CF_TABLE_BEGIN(g_ObjectInfo)
  40. CF_TABLE_ENTRY( &CLSID_DsPropertyPages, CDsPropertyPages_CreateInstance, COCREATEONLY),
  41. CF_TABLE_ENTRY( &CLSID_DsDomainTreeBrowser, CDsDomainTreeBrowser_CreateInstance, COCREATEONLY),
  42. CF_TABLE_ENTRY( &CLSID_DsVerbs, CDsVerbs_CreateInstance, COCREATEONLY),
  43. CF_TABLE_ENTRY( &CLSID_DsDisplaySpecifier, CDsDisplaySpecifier_CreateInstance, COCREATEONLY),
  44. CF_TABLE_END(g_ObjectInfo)
  45. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
  46. {
  47. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  48. {
  49. for (LPCOBJECTINFO pcls = g_ObjectInfo; pcls->pclsid; pcls++)
  50. {
  51. if (IsEqualGUID(rclsid, *(pcls->pclsid)))
  52. {
  53. *ppv = (void*)pcls;
  54. DllAddRef();
  55. return NOERROR;
  56. }
  57. }
  58. }
  59. *ppv = NULL;
  60. return CLASS_E_CLASSNOTAVAILABLE;
  61. }
  62. // registration
  63. STDAPI DllRegisterServer(VOID)
  64. {
  65. return CallRegInstall(GLOBAL_HINSTANCE, "RegDll");
  66. }
  67. STDAPI DllUnregisterServer(VOID)
  68. {
  69. return CallRegInstall(GLOBAL_HINSTANCE, "UnRegDll");
  70. }
  71. STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
  72. {
  73. return S_OK;
  74. }
  75. // static class factory
  76. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void **ppvObj)
  77. {
  78. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  79. {
  80. *ppvObj = (void *)GET_ICLASSFACTORY(this);
  81. InterlockedIncrement(&g_cRef);
  82. return NOERROR;
  83. }
  84. *ppvObj = NULL;
  85. return E_NOINTERFACE;
  86. }
  87. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  88. {
  89. InterlockedIncrement(&g_cRef);
  90. return 2;
  91. }
  92. STDMETHODIMP_(ULONG) CClassFactory::Release()
  93. {
  94. InterlockedDecrement(&g_cRef);
  95. return 1;
  96. }
  97. STDMETHODIMP CClassFactory::CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv)
  98. {
  99. *ppv = NULL;
  100. if (punkOuter && !IsEqualIID(riid, IID_IUnknown))
  101. {
  102. // It is technically illegal to aggregate an object and request
  103. // any interface other than IUnknown. Enforce this.
  104. //
  105. return CLASS_E_NOAGGREGATION;
  106. }
  107. else
  108. {
  109. LPOBJECTINFO pthisobj = (LPOBJECTINFO)this;
  110. if ( punkOuter )
  111. return CLASS_E_NOAGGREGATION;
  112. IUnknown *punk;
  113. HRESULT hres = pthisobj->pfnCreateInstance(punkOuter, &punk, pthisobj);
  114. if (SUCCEEDED(hres))
  115. {
  116. hres = punk->QueryInterface(riid, ppv);
  117. punk->Release();
  118. }
  119. return hres;
  120. }
  121. }
  122. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  123. {
  124. if (fLock)
  125. InterlockedIncrement(&g_cRef);
  126. else
  127. InterlockedDecrement(&g_cRef);
  128. return S_OK;
  129. }