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.

314 lines
7.8 KiB

  1. // Copyright (C) 1996-1997 Microsoft Corporation. All rights reserved.
  2. #include "header.h"
  3. #include "ClassF.H"
  4. #include "Unknown.H" // for CREATEFNOFOBJECT
  5. #include "localobj.h"
  6. #include "localsrv.h"
  7. #ifndef _DEBUG
  8. #undef THIS_FILE
  9. static const char THIS_FILE[] = __FILE__;
  10. #endif
  11. HRESULT CreateOleObjectFromIndex(IUnknown *, int Index, void **, REFIID);
  12. CClassFactory::CClassFactory(int iIndex)
  13. {
  14. m_iIndex = iIndex;
  15. m_cRefs = 1;
  16. }
  17. CClassFactory::~CClassFactory ()
  18. {
  19. ASSERT_COMMENT(m_cRefs == 0, "Object being deleted with refs!");
  20. return;
  21. }
  22. //=--------------------------------------------------------------------------=
  23. // CClassFactory::QueryInterface
  24. //=--------------------------------------------------------------------------=
  25. // the user wants another interface. we won't give 'em. very many.
  26. //
  27. // Parameters:
  28. // REFIID - [in] interface they want
  29. // void ** - [out] where they want to put the resulting object ptr.
  30. //
  31. // Output:
  32. // HRESULT - S_OK, E_NOINTERFACE
  33. //
  34. // Notes:
  35. //
  36. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void **ppvObjOut)
  37. {
  38. void *pv;
  39. CHECK_POINTER(ppvObjOut);
  40. // we support IUnknown, and the two CF interfaces
  41. //
  42. if (DO_GUIDS_MATCH(riid, IID_IClassFactory)) {
  43. pv = (void *)(IClassFactory *)this;
  44. } else if (DO_GUIDS_MATCH(riid, IID_IClassFactory2)) {
  45. pv = (void *)(IClassFactory2 *)this;
  46. } else if (DO_GUIDS_MATCH(riid, IID_IUnknown)) {
  47. pv = (void *)(IUnknown *)this;
  48. } else {
  49. *ppvObjOut = NULL;
  50. return E_NOINTERFACE;
  51. }
  52. ((IUnknown *)pv)->AddRef();
  53. *ppvObjOut = pv;
  54. return S_OK;
  55. }
  56. //=--------------------------------------------------------------------------=
  57. // CClassFactory::AddRef
  58. //=--------------------------------------------------------------------------=
  59. // adds a tick to the current reference count.
  60. //
  61. // Output:
  62. // ULONG - the new reference count
  63. ULONG CClassFactory::AddRef(void)
  64. {
  65. return ++m_cRefs;
  66. }
  67. //=--------------------------------------------------------------------------=
  68. // CClassFactory::Release
  69. //=--------------------------------------------------------------------------=
  70. // removes a tick from the count, and delets the object if necessary
  71. //
  72. // Output:
  73. // ULONG - remaining refs
  74. ULONG CClassFactory::Release(void)
  75. {
  76. ASSERT_COMMENT(m_cRefs, "No Refs, and we're being released!");
  77. if(--m_cRefs)
  78. return m_cRefs;
  79. delete this;
  80. return 0;
  81. }
  82. //=--------------------------------------------------------------------------=
  83. // CClassFactory::CreateInstance
  84. //=--------------------------------------------------------------------------=
  85. // create an instance of some sort of object.
  86. //
  87. // Parameters:
  88. // IUnknown * - [in] controlling IUknonwn for aggregation
  89. // REFIID - [in] interface id for new object
  90. // void ** - [out] pointer to new interface object.
  91. //
  92. // Output:
  93. // HRESULT - S_OK, E_NOINTERFACE, E_UNEXPECTED,
  94. // E_OUTOFMEMORY, E_INVALIDARG
  95. //
  96. // Notes:
  97. //
  98. STDMETHODIMP CClassFactory::CreateInstance
  99. (
  100. IUnknown *pUnkOuter,
  101. REFIID riid,
  102. void **ppvObjOut
  103. )
  104. {
  105. // check args
  106. //
  107. if (!ppvObjOut)
  108. return E_INVALIDARG;
  109. // check to see if we've done our licensing work. we do this as late
  110. // as possible that people calling CreateInstanceLic don't suffer from
  111. // a performance hit here.
  112. //
  113. // crit sect this for apartment threading, since it's global
  114. //
  115. // EnterCriticalSection(&g_CriticalSection);
  116. if (!g_fCheckedForLicense) {
  117. g_fMachineHasLicense = TRUE; // 17-Jun-1997 [ralphw] no license check
  118. g_fCheckedForLicense = TRUE;
  119. }
  120. // LeaveCriticalSection(&g_CriticalSection);
  121. // check to see if they have the appropriate license to create this stuff
  122. //
  123. // 08-Jan-1997 [ralphw] CLASS_E_NOTLICENSED disappeared from the header files
  124. //
  125. // if (!g_fMachineHasLicense)
  126. // return CLASS_E_NOTLICENSED;
  127. // try to create one of the objects that we support
  128. //
  129. return CreateOleObjectFromIndex(pUnkOuter, m_iIndex, ppvObjOut, riid);
  130. }
  131. //=--------------------------------------------------------------------------=
  132. // CClassFactory::LockServer
  133. //=--------------------------------------------------------------------------=
  134. // lock the server so we can't unload
  135. //
  136. // Parameters:
  137. // BOOL - [in] TRUE means addref, false means release lock count.
  138. //
  139. // Output:
  140. // HRESULT - S_OK, E_FAIL, E_OUTOFMEMORY, E_UNEXPECTED
  141. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  142. {
  143. // update the lock count. crit sect these in case of another thread.
  144. if (fLock)
  145. InterlockedIncrement(&g_cLocks);
  146. else {
  147. ASSERT_COMMENT(g_cLocks, "Lock Counting Problem");
  148. InterlockedDecrement(&g_cLocks);
  149. }
  150. return S_OK;
  151. }
  152. //=--------------------------------------------------------------------------=
  153. // CClassFactory::GetLicInfo
  154. //=--------------------------------------------------------------------------=
  155. // IClassFactory2 GetLicInfo
  156. //
  157. // Parameters:
  158. // LICINFO * - unclear
  159. //
  160. // Output:
  161. // HRESULT - unclear
  162. //
  163. // Notes:
  164. //
  165. STDMETHODIMP CClassFactory::GetLicInfo
  166. (
  167. LICINFO *pLicInfo
  168. )
  169. {
  170. CHECK_POINTER(pLicInfo);
  171. pLicInfo->cbLicInfo = sizeof(LICINFO);
  172. // This says whether RequestLicKey will work
  173. pLicInfo->fRuntimeKeyAvail = g_fMachineHasLicense;
  174. // This says whether the standard CreateInstance will work
  175. pLicInfo->fLicVerified = g_fMachineHasLicense;
  176. return S_OK;
  177. }
  178. //=--------------------------------------------------------------------------=
  179. // CClassFactory::RequestLicKey
  180. //=--------------------------------------------------------------------------=
  181. // IClassFactory2 RequestLicKey
  182. //
  183. // Parameters:
  184. // DWORD - [in] reserved
  185. // BSTR * - [out] unclear
  186. //
  187. // Output:
  188. // HRESULT - unclear
  189. //
  190. // Notes:
  191. //
  192. STDMETHODIMP CClassFactory::RequestLicKey(DWORD dwReserved, BSTR *pbstr)
  193. {
  194. *pbstr = NULL;
  195. return (*pbstr) ? S_OK : E_OUTOFMEMORY;
  196. }
  197. //=--------------------------------------------------------------------------=
  198. // CClassFactory::CreateInstanceLic
  199. //=--------------------------------------------------------------------------=
  200. // create a new instance given a licensing key, etc ...
  201. //
  202. // Parameters:
  203. // IUnknown * - [in] controlling IUnknown for aggregation
  204. // IUnknown * - [in] reserved, must be NULL
  205. // REFIID - [in] IID We're looking for.
  206. // BSTR - [in] license key
  207. // void ** - [out] where to put the new object.
  208. //
  209. // Output:
  210. // HRESULT - unclear
  211. //
  212. // Notes:
  213. //
  214. STDMETHODIMP CClassFactory::CreateInstanceLic
  215. (
  216. IUnknown *pUnkOuter,
  217. IUnknown *pUnkReserved,
  218. REFIID riid,
  219. BSTR bstrKey,
  220. void **ppvObjOut
  221. )
  222. {
  223. *ppvObjOut = NULL;
  224. return CreateOleObjectFromIndex(pUnkOuter, m_iIndex, ppvObjOut, riid);
  225. }
  226. //=--------------------------------------------------------------------------=
  227. // CreateOleObjectFromIndex
  228. //=--------------------------------------------------------------------------=
  229. // given an index in our object table, create an object from it.
  230. //
  231. // Parameters:
  232. // IUnknown * - [in] Controlling Unknown, if any, for aggregation
  233. // int - [in] index into our global table
  234. // void ** - [out] where to put resulting object.
  235. // REFIID - [in] the interface they want resulting object to be.
  236. //
  237. // Output:
  238. // HRESULT - S_OK, E_OUTOFMEMORY, E_NOINTERFACE
  239. HRESULT CreateOleObjectFromIndex
  240. (
  241. IUnknown *pUnkOuter,
  242. int iIndex,
  243. void **ppvObjOut,
  244. REFIID riid
  245. )
  246. {
  247. ASSERT_COMMENT(CREATEFNOFOBJECT(iIndex), "All creatable objects must have creation fn!");
  248. IUnknown* pUnk = CREATEFNOFOBJECT(iIndex)(pUnkOuter);
  249. // sanity check and make sure the object actually got allocated.
  250. RETURN_ON_NULLALLOC(pUnk);
  251. // make sure we support aggregation here properly -- if they gave us
  252. // a controlling unknown, then they -must- ask for IUnknown, and we'll
  253. // give them the private unknown the object gave us.
  254. HRESULT hr;
  255. if (pUnkOuter) {
  256. if (!DO_GUIDS_MATCH(riid, IID_IUnknown)) {
  257. pUnk->Release();
  258. return E_INVALIDARG;
  259. }
  260. *ppvObjOut = (void *)pUnk;
  261. hr = S_OK;
  262. } else {
  263. // QI for whatever the user wants.
  264. hr = pUnk->QueryInterface(riid, ppvObjOut);
  265. pUnk->Release();
  266. RETURN_ON_FAILURE(hr);
  267. }
  268. return hr;
  269. }