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.

230 lines
5.4 KiB

  1. //==============================================================;
  2. //
  3. // This source code is only intended as a supplement to existing Microsoft documentation.
  4. //
  5. //
  6. //
  7. //
  8. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  9. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  10. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  11. // PURPOSE.
  12. //
  13. // Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  14. //
  15. //
  16. //
  17. //==============================================================;
  18. #include <objbase.h>
  19. #include <olectl.h>
  20. #include <initguid.h>
  21. #include "globals.h"
  22. #include "resource.h"
  23. #include "guids.h"
  24. #include "basesnap.h"
  25. #include "CMenuExt.h"
  26. #include "About.h"
  27. #include "Registry.h"
  28. #include "Extend.h"
  29. // our globals
  30. HINSTANCE g_hinst;
  31. BOOL WINAPI DllMain(HINSTANCE hinstDLL,
  32. DWORD fdwReason,
  33. void* lpvReserved)
  34. {
  35. if (fdwReason == DLL_PROCESS_ATTACH) {
  36. g_hinst = hinstDLL;
  37. }
  38. return TRUE;
  39. }
  40. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvObj)
  41. {
  42. if ((rclsid != CLSID_CContextMenuExtension) && (rclsid != CLSID_CSnapinAbout))
  43. return CLASS_E_CLASSNOTAVAILABLE;
  44. if (!ppvObj)
  45. return E_FAIL;
  46. *ppvObj = NULL;
  47. // We can only hand out IUnknown and IClassFactory pointers. Fail
  48. // if they ask for anything else.
  49. if (!IsEqualIID(riid, IID_IUnknown) && !IsEqualIID(riid, IID_IClassFactory))
  50. return E_NOINTERFACE;
  51. CClassFactory *pFactory = NULL;
  52. // make the factory passing in the creation function for the type of object they want
  53. if (rclsid == CLSID_CContextMenuExtension)
  54. pFactory = new CClassFactory(CClassFactory::CONTEXTEXTENSION);
  55. else if (rclsid == CLSID_CSnapinAbout)
  56. pFactory = new CClassFactory(CClassFactory::ABOUT);
  57. if (NULL == pFactory)
  58. return E_OUTOFMEMORY;
  59. HRESULT hr = pFactory->QueryInterface(riid, ppvObj);
  60. return hr;
  61. }
  62. STDAPI DllCanUnloadNow(void)
  63. {
  64. if (g_uObjects == 0 && g_uSrvLock == 0)
  65. return S_OK;
  66. else
  67. return S_FALSE;
  68. }
  69. CClassFactory::CClassFactory(FACTORY_TYPE factoryType)
  70. : m_cref(0), m_factoryType(factoryType)
  71. {
  72. OBJECT_CREATED
  73. }
  74. CClassFactory::~CClassFactory()
  75. {
  76. OBJECT_DESTROYED
  77. }
  78. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, LPVOID *ppv)
  79. {
  80. if (!ppv)
  81. return E_FAIL;
  82. *ppv = NULL;
  83. if (IsEqualIID(riid, IID_IUnknown))
  84. *ppv = static_cast<IClassFactory *>(this);
  85. else
  86. if (IsEqualIID(riid, IID_IClassFactory))
  87. *ppv = static_cast<IClassFactory *>(this);
  88. if (*ppv)
  89. {
  90. reinterpret_cast<IUnknown *>(*ppv)->AddRef();
  91. return S_OK;
  92. }
  93. return E_NOINTERFACE;
  94. }
  95. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  96. {
  97. return InterlockedIncrement((LONG *)&m_cref);
  98. }
  99. STDMETHODIMP_(ULONG) CClassFactory::Release()
  100. {
  101. if (InterlockedDecrement((LONG *)&m_cref) == 0)
  102. {
  103. delete this;
  104. return 0;
  105. }
  106. return m_cref;
  107. }
  108. STDMETHODIMP CClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObj)
  109. {
  110. HRESULT hr;
  111. void* pObj;
  112. if (!ppvObj)
  113. return E_FAIL;
  114. *ppvObj = NULL;
  115. // Our object does does not support aggregation, so we need to
  116. // fail if they ask us to do aggregation.
  117. if (pUnkOuter)
  118. return CLASS_E_NOAGGREGATION;
  119. if (CONTEXTEXTENSION == m_factoryType) {
  120. pObj = new CContextMenuExtension();
  121. } else {
  122. pObj = new CSnapinAbout();
  123. }
  124. if (!pObj)
  125. return E_OUTOFMEMORY;
  126. // QueryInterface will do the AddRef() for us, so we do not
  127. // do it in this function
  128. hr = ((LPUNKNOWN)pObj)->QueryInterface(riid, ppvObj);
  129. if (FAILED(hr))
  130. delete pObj;
  131. return hr;
  132. }
  133. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  134. {
  135. if (fLock)
  136. InterlockedIncrement((LONG *)&g_uSrvLock);
  137. else
  138. InterlockedDecrement((LONG *)&g_uSrvLock);
  139. return S_OK;
  140. }
  141. //////////////////////////////////////////////////////////
  142. //
  143. // Exported functions
  144. //
  145. //
  146. // Server registration
  147. //
  148. STDAPI DllRegisterServer()
  149. {
  150. HRESULT hr = SELFREG_E_CLASS;
  151. _TCHAR szName[256];
  152. _TCHAR szSnapInName[256];
  153. LoadString(g_hinst, IDS_NAME, szName, sizeof(szName));
  154. LoadString(g_hinst, IDS_SNAPINNAME, szSnapInName, sizeof(szSnapInName));
  155. _TCHAR szAboutName[256];
  156. LoadString(g_hinst, IDS_ABOUTNAME, szAboutName, sizeof(szAboutName));
  157. // register our CoClasses
  158. hr = RegisterServer(g_hinst,
  159. CLSID_CContextMenuExtension,
  160. szName);
  161. if SUCCEEDED(hr)
  162. hr = RegisterServer(g_hinst,
  163. CLSID_CSnapinAbout,
  164. szAboutName);
  165. // place the registry information for SnapIns
  166. if SUCCEEDED(hr)
  167. hr = RegisterSnapin(CLSID_CContextMenuExtension, szSnapInName, CLSID_CSnapinAbout);
  168. return hr;
  169. }
  170. STDAPI DllUnregisterServer()
  171. {
  172. if (UnregisterServer(CLSID_CContextMenuExtension) == S_OK)
  173. return UnregisterSnapin(CLSID_CContextMenuExtension);
  174. else
  175. return E_FAIL;
  176. }