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.

396 lines
11 KiB

  1. //=--------------------------------------------------------------------------=
  2. // ClassF.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1996 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // contains the implementation of the ClassFactory object. we support
  13. // IClassFactory and IClassFactory2
  14. //
  15. #include "IPServer.H"
  16. #include "LocalSrv.H"
  17. #include "ClassF.H"
  18. #include "Globals.H"
  19. #include "Unknown.H" // for CREATEFNOFOBJECT
  20. //=--------------------------------------------------------------------------=
  21. // private module level data
  22. //=--------------------------------------------------------------------------=
  23. //
  24. // ASSERT and FAIL require this
  25. //
  26. SZTHISFILE
  27. // private routines for this file
  28. //
  29. HRESULT CreateOleObjectFromIndex(IUnknown *, int Index, void **, REFIID);
  30. //=--------------------------------------------------------------------------=
  31. // CClassFactory::CClassFactory
  32. //=--------------------------------------------------------------------------=
  33. // create the object and initialize the refcount
  34. //
  35. // Parameters:
  36. // int - [in] index into our global table of objects for this guy
  37. //
  38. // Notes:
  39. //
  40. CClassFactory::CClassFactory
  41. (
  42. int iIndex
  43. )
  44. : m_iIndex(iIndex)
  45. {
  46. m_cRefs = 1;
  47. }
  48. //=--------------------------------------------------------------------------=
  49. // CClassFactory::CClassFactory
  50. //=--------------------------------------------------------------------------=
  51. // "Life levels all men. Death reveals the eminent."
  52. // - George Bernard Shaw (1856 - 1950)
  53. //
  54. // Notes:
  55. //
  56. CClassFactory::~CClassFactory ()
  57. {
  58. ASSERT(m_cRefs == 0, "Object being deleted with refs!");
  59. return;
  60. }
  61. //=--------------------------------------------------------------------------=
  62. // CClassFactory::QueryInterface
  63. //=--------------------------------------------------------------------------=
  64. // the user wants another interface. we won't give 'em. very many.
  65. //
  66. // Parameters:
  67. // REFIID - [in] interface they want
  68. // void ** - [out] where they want to put the resulting object ptr.
  69. //
  70. // Output:
  71. // HRESULT - S_OK, E_NOINTERFACE
  72. //
  73. // Notes:
  74. //
  75. STDMETHODIMP CClassFactory::QueryInterface
  76. (
  77. REFIID riid,
  78. void **ppvObjOut
  79. )
  80. {
  81. void *pv;
  82. CHECK_POINTER(ppvObjOut);
  83. // we support IUnknown, and the two CF interfaces
  84. //
  85. if (DO_GUIDS_MATCH(riid, IID_IClassFactory)) {
  86. pv = (void *)(IClassFactory *)this;
  87. } else if (DO_GUIDS_MATCH(riid, IID_IClassFactory2)) {
  88. pv = (void *)(IClassFactory2 *)this;
  89. } else if (DO_GUIDS_MATCH(riid, IID_IUnknown)) {
  90. pv = (void *)(IUnknown *)this;
  91. } else {
  92. *ppvObjOut = NULL;
  93. return E_NOINTERFACE;
  94. }
  95. ((IUnknown *)pv)->AddRef();
  96. *ppvObjOut = pv;
  97. return S_OK;
  98. }
  99. //=--------------------------------------------------------------------------=
  100. // CClassFactory::AddRef
  101. //=--------------------------------------------------------------------------=
  102. // adds a tick to the current reference count.
  103. //
  104. // Output:
  105. // ULONG - the new reference count
  106. //
  107. // Notes:
  108. //
  109. ULONG CClassFactory::AddRef
  110. (
  111. void
  112. )
  113. {
  114. return ++m_cRefs;
  115. }
  116. //=--------------------------------------------------------------------------=
  117. // CClassFactory::Release
  118. //=--------------------------------------------------------------------------=
  119. // removes a tick from the count, and delets the object if necessary
  120. //
  121. // Output:
  122. // ULONG - remaining refs
  123. //
  124. // Notes:
  125. //
  126. ULONG CClassFactory::Release
  127. (
  128. void
  129. )
  130. {
  131. ASSERT(m_cRefs, "No Refs, and we're being released!");
  132. if(--m_cRefs)
  133. return m_cRefs;
  134. delete this;
  135. return 0;
  136. }
  137. //=--------------------------------------------------------------------------=
  138. // CClassFactory::CreateInstance
  139. //=--------------------------------------------------------------------------=
  140. // create an instance of some sort of object.
  141. //
  142. // Parameters:
  143. // IUnknown * - [in] controlling IUknonwn for aggregation
  144. // REFIID - [in] interface id for new object
  145. // void ** - [out] pointer to new interface object.
  146. //
  147. // Output:
  148. // HRESULT - S_OK, E_NOINTERFACE, E_UNEXPECTED,
  149. // E_OUTOFMEMORY, E_INVALIDARG
  150. //
  151. // Notes:
  152. //
  153. STDMETHODIMP CClassFactory::CreateInstance
  154. (
  155. IUnknown *pUnkOuter,
  156. REFIID riid,
  157. void **ppvObjOut
  158. )
  159. {
  160. // check args
  161. //
  162. if (!ppvObjOut)
  163. return E_INVALIDARG;
  164. // check to see if we've done our licensing work. we do this as late
  165. // as possible that people calling CreateInstanceLic don't suffer from
  166. // a performance hit here.
  167. //
  168. // crit sect this for apartment threading, since it's global
  169. //
  170. EnterCriticalSection(&g_CriticalSection);
  171. if (!g_fCheckedForLicense) {
  172. g_fMachineHasLicense = CheckForLicense();
  173. g_fCheckedForLicense = TRUE;
  174. }
  175. LeaveCriticalSection(&g_CriticalSection);
  176. // check to see if they have the appropriate license to create this stuff
  177. //
  178. if (!g_fMachineHasLicense)
  179. return CLASS_E_NOTLICENSED;
  180. // try to create one of the objects that we support
  181. //
  182. return CreateOleObjectFromIndex(pUnkOuter, m_iIndex, ppvObjOut, riid);
  183. }
  184. //=--------------------------------------------------------------------------=
  185. // CClassFactory::LockServer
  186. //=--------------------------------------------------------------------------=
  187. // lock the server so we can't unload
  188. //
  189. // Parameters:
  190. // BOOL - [in] TRUE means addref, false means release lock count.
  191. //
  192. // Output:
  193. // HRESULT - S_OK, E_FAIL, E_OUTOFMEMORY, E_UNEXPECTED
  194. //
  195. // Notes:
  196. //
  197. STDMETHODIMP CClassFactory::LockServer
  198. (
  199. BOOL fLock
  200. )
  201. {
  202. // update the lock count. crit sect these in case of another thread.
  203. //
  204. if (fLock)
  205. InterlockedIncrement(&g_cLocks);
  206. else {
  207. ASSERT(g_cLocks, "D'oh! Lock Counting Problem");
  208. InterlockedDecrement(&g_cLocks);
  209. }
  210. return S_OK;
  211. }
  212. //=--------------------------------------------------------------------------=
  213. // CClassFactory::GetLicInfo
  214. //=--------------------------------------------------------------------------=
  215. // IClassFactory2 GetLicInfo
  216. //
  217. // Parameters:
  218. // LICINFO * - unclear
  219. //
  220. // Output:
  221. // HRESULT - unclear
  222. //
  223. // Notes:
  224. //
  225. STDMETHODIMP CClassFactory::GetLicInfo
  226. (
  227. LICINFO *pLicInfo
  228. )
  229. {
  230. CHECK_POINTER(pLicInfo);
  231. pLicInfo->cbLicInfo = sizeof(LICINFO);
  232. // This says whether RequestLicKey will work
  233. //
  234. pLicInfo->fRuntimeKeyAvail = g_fMachineHasLicense;
  235. // This says whether the standard CreateInstance will work
  236. //
  237. pLicInfo->fLicVerified = g_fMachineHasLicense;
  238. return S_OK;
  239. }
  240. //=--------------------------------------------------------------------------=
  241. // CClassFactory::RequestLicKey
  242. //=--------------------------------------------------------------------------=
  243. // IClassFactory2 RequestLicKey
  244. //
  245. // Parameters:
  246. // DWORD - [in] reserved
  247. // BSTR * - [out] unclear
  248. //
  249. // Output:
  250. // HRESULT - unclear
  251. //
  252. // Notes:
  253. //
  254. STDMETHODIMP CClassFactory::RequestLicKey
  255. (
  256. DWORD dwReserved,
  257. BSTR *pbstr
  258. )
  259. {
  260. // if the machine isn't licensed, then we're not about to give this to them !
  261. //
  262. if (!g_fMachineHasLicense)
  263. return CLASS_E_NOTLICENSED;
  264. *pbstr = GetLicenseKey();
  265. return (*pbstr) ? S_OK : E_OUTOFMEMORY;
  266. }
  267. //=--------------------------------------------------------------------------=
  268. // CClassFactory::CreateInstanceLic
  269. //=--------------------------------------------------------------------------=
  270. // create a new instance given a licensing key, etc ...
  271. //
  272. // Parameters:
  273. // IUnknown * - [in] controlling IUnknown for aggregation
  274. // IUnknown * - [in] reserved, must be NULL
  275. // REFIID - [in] IID We're looking for.
  276. // BSTR - [in] license key
  277. // void ** - [out] where to put the new object.
  278. //
  279. // Output:
  280. // HRESULT - unclear
  281. //
  282. // Notes:
  283. //
  284. STDMETHODIMP CClassFactory::CreateInstanceLic
  285. (
  286. IUnknown *pUnkOuter,
  287. IUnknown *pUnkReserved,
  288. REFIID riid,
  289. BSTR bstrKey,
  290. void **ppvObjOut
  291. )
  292. {
  293. *ppvObjOut = NULL;
  294. // go and see if the key they gave us matches.
  295. //
  296. if (!CheckLicenseKey(bstrKey))
  297. return CLASS_E_NOTLICENSED;
  298. // if it does, then go and create the object.
  299. //
  300. return CreateOleObjectFromIndex(pUnkOuter, m_iIndex, ppvObjOut, riid);
  301. }
  302. //=--------------------------------------------------------------------------=
  303. // CreateOleObjectFromIndex
  304. //=--------------------------------------------------------------------------=
  305. // given an index in our object table, create an object from it.
  306. //
  307. // Parameters:
  308. // IUnknown * - [in] Controlling Unknown, if any, for aggregation
  309. // int - [in] index into our global table
  310. // void ** - [out] where to put resulting object.
  311. // REFIID - [in] the interface they want resulting object to be.
  312. //
  313. // Output:
  314. // HRESULT - S_OK, E_OUTOFMEMORY, E_NOINTERFACE
  315. //
  316. // Notes:
  317. //
  318. HRESULT CreateOleObjectFromIndex
  319. (
  320. IUnknown *pUnkOuter,
  321. int iIndex,
  322. void **ppvObjOut,
  323. REFIID riid
  324. )
  325. {
  326. IUnknown *pUnk = NULL;
  327. HRESULT hr;
  328. // go and create the object
  329. //
  330. ASSERT(CREATEFNOFOBJECT(iIndex), "All creatable objects must have creation fn!");
  331. pUnk = CREATEFNOFOBJECT(iIndex)(pUnkOuter);
  332. // sanity check and make sure the object actually got allocated.
  333. //
  334. RETURN_ON_NULLALLOC(pUnk);
  335. // make sure we support aggregation here properly -- if they gave us
  336. // a controlling unknown, then they -must- ask for IUnknown, and we'll
  337. // give them the private unknown the object gave us.
  338. //
  339. if (pUnkOuter) {
  340. if (!DO_GUIDS_MATCH(riid, IID_IUnknown)) {
  341. pUnk->Release();
  342. return E_INVALIDARG;
  343. }
  344. *ppvObjOut = (void *)pUnk;
  345. hr = S_OK;
  346. } else {
  347. // QI for whatever the user wants.
  348. //
  349. hr = pUnk->QueryInterface(riid, ppvObjOut);
  350. pUnk->Release();
  351. RETURN_ON_FAILURE(hr);
  352. }
  353. return hr;
  354. }