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.2 KiB

  1. //+------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1997
  5. //
  6. // File: cclstor.cxx
  7. //
  8. // Contents:Class Factory and IUnknown methods for CClassContainer
  9. //
  10. // Author: DebiM
  11. //
  12. //-------------------------------------------------------------------------
  13. #include "csadm.hxx"
  14. //
  15. // Constructor for Class Container Class factory
  16. //
  17. unsigned long gulcInstances = 0;
  18. CClassContainerCF::CClassContainerCF()
  19. {
  20. m_uRefs = 1;
  21. InterlockedIncrement((long *) &gulcInstances );
  22. }
  23. //
  24. // Destructor
  25. //
  26. CClassContainerCF::~CClassContainerCF()
  27. {
  28. InterlockedDecrement((long *) &gulcInstances );
  29. }
  30. HRESULT __stdcall CClassContainerCF::QueryInterface(REFIID riid, void * * ppvObject)
  31. {
  32. IUnknown *pUnkTemp = NULL;
  33. SCODE sc = S_OK;
  34. if( IsEqualIID( IID_IUnknown, riid ) )
  35. {
  36. pUnkTemp = (IUnknown *)(ITypeLib *)this;
  37. }
  38. else if( IsEqualIID( IID_IClassFactory, riid ) )
  39. {
  40. pUnkTemp = (IUnknown *)(IClassFactory *)this;
  41. }
  42. else if( IsEqualIID( IID_IParseDisplayName, riid ) )
  43. {
  44. pUnkTemp = (IUnknown *)(IParseDisplayName *)this;
  45. }
  46. else
  47. {
  48. sc = (E_NOINTERFACE);
  49. }
  50. if((pUnkTemp != NULL) && (SUCCEEDED(sc)))
  51. {
  52. *ppvObject = (void * )pUnkTemp;
  53. pUnkTemp->AddRef();
  54. }
  55. return(sc);
  56. }
  57. ULONG __stdcall CClassContainerCF::AddRef()
  58. {
  59. InterlockedIncrement(( long * )&m_uRefs );
  60. return m_uRefs;
  61. }
  62. ULONG __stdcall CClassContainerCF::Release()
  63. {
  64. unsigned long uTmp = InterlockedDecrement((long *)&m_uRefs);
  65. unsigned long cRef = m_uRefs;
  66. if (uTmp == 0)
  67. {
  68. delete this;
  69. }
  70. return(cRef);
  71. }
  72. //+-------------------------------------------------------------------------
  73. //
  74. // Member: CClassContainerCF::CreateInstance
  75. //
  76. // Synopsis:
  77. // This is the default create instance on the class factory.
  78. //
  79. // Arguments: pUnkOuter - Should be NULL
  80. // riid - IID of interface wanted
  81. // ppvObject - Returns the pointer to the resulting IClassAdmin.
  82. //
  83. // Returns: S_OK
  84. // E_INVALIDARG
  85. // E_OUTOFMEMORY
  86. // MK_E_SYNTAX
  87. //
  88. //--------------------------------------------------------------------------
  89. //
  90. HRESULT __stdcall CClassContainerCF::CreateInstance(
  91. IUnknown * pUnkOuter,
  92. REFIID riid,
  93. void ** ppvObject)
  94. {
  95. CClassContainer * pIUnk = NULL;
  96. SCODE sc = S_OK;
  97. if( pUnkOuter == NULL )
  98. {
  99. if( (pIUnk = new CClassContainer()) != NULL)
  100. {
  101. sc = pIUnk->QueryInterface( riid , ppvObject );
  102. if(FAILED(sc))
  103. {
  104. sc = E_UNEXPECTED;
  105. }
  106. pIUnk->Release();
  107. }
  108. else
  109. sc = E_OUTOFMEMORY;
  110. }
  111. else
  112. {
  113. return E_INVALIDARG;
  114. }
  115. return (sc);
  116. }
  117. //+-------------------------------------------------------------------------
  118. //
  119. // Member: CClassContainerCF::CreateConnectedInstance
  120. //
  121. // Synopsis:
  122. // This method is called by the ParseDisplayName implementation
  123. // on the ClassFactory object.
  124. // When a display name is used to bind to a Class Store
  125. // an IClassAdmin is returned after binding to the container.
  126. // This method fails if the bind fails.
  127. //
  128. // Arguments: pszPath - DisplayName of Class Store Container
  129. // ppvObject - Returns the pointer to the resulting IClassAdmin.
  130. //
  131. // Returns: S_OK
  132. // E_INVALIDARG
  133. // E_OUTOFMEMORY
  134. // MK_E_SYNTAX
  135. //
  136. //--------------------------------------------------------------------------
  137. HRESULT __stdcall CClassContainerCF::CreateConnectedInstance(
  138. LPOLESTR pszPath,
  139. void ** ppvObject)
  140. {
  141. CClassContainer * pIUnk = NULL;
  142. SCODE sc = S_OK;
  143. HRESULT hr;
  144. if ((pIUnk = new CClassContainer(pszPath, &sc)) != NULL)
  145. {
  146. if (SUCCEEDED(sc))
  147. {
  148. sc = pIUnk->QueryInterface( IID_IClassAdmin, ppvObject );
  149. if(FAILED(sc))
  150. {
  151. sc = E_UNEXPECTED;
  152. }
  153. }
  154. else
  155. printf ("Connect to Store Failed. hr = 0x%x.\n", sc);
  156. pIUnk->Release();
  157. }
  158. else
  159. sc = E_OUTOFMEMORY;
  160. return (sc);
  161. }
  162. //+-------------------------------------------------------------------------
  163. //
  164. // Member: CClassContainerCF::ParseDisplayName
  165. //
  166. // Synopsis: Parse a display name and create a pointer moniker.
  167. //
  168. // Arguments: pbc - Supplies bind context.
  169. // pszDisplayName - Supplies display name to be parsed.
  170. // pchEaten - Returns the number of characters parsed.
  171. // ppmkOut - Returns the pointer to the resulting moniker.
  172. //
  173. // Returns: S_OK
  174. // E_INVALIDARG
  175. // E_OUTOFMEMORY
  176. // MK_E_SYNTAX
  177. //
  178. //--------------------------------------------------------------------------
  179. STDMETHODIMP CClassContainerCF::ParseDisplayName(
  180. IBindCtx * pbc,
  181. LPOLESTR pszDisplayName,
  182. ULONG * pchEaten,
  183. IMoniker ** ppmkOut)
  184. {
  185. HRESULT hr = S_OK;
  186. LPOLESTR pch = pszDisplayName;
  187. IClassAdmin * pOleClassStore = NULL;
  188. DWORD ClassStoreId;
  189. //Validate parameters.
  190. *pchEaten = 0;
  191. *ppmkOut = NULL;
  192. //Eat the prefix.
  193. while (*pch != '\0' && *pch != ':')
  194. {
  195. pch++;
  196. }
  197. if(':' == *pch)
  198. {
  199. pch++;
  200. }
  201. else
  202. {
  203. return MK_E_SYNTAX;
  204. }
  205. hr = CreateConnectedInstance(pch, (void **) &pOleClassStore);
  206. if(SUCCEEDED(hr))
  207. {
  208. hr = CreatePointerMoniker(pOleClassStore, ppmkOut);
  209. if(SUCCEEDED(hr))
  210. {
  211. *pchEaten = lstrlenW(pszDisplayName);
  212. }
  213. pOleClassStore->Release();
  214. }
  215. return hr;
  216. }
  217. HRESULT __stdcall CClassContainerCF::LockServer(BOOL fLock)
  218. {
  219. if(fLock)
  220. { InterlockedIncrement((long *) &gulcInstances ); }
  221. else
  222. { InterlockedDecrement((long *) &gulcInstances ); }
  223. return(S_OK);
  224. }
  225. //
  226. // IUnknown methods for CClassContainer
  227. //
  228. //
  229. HRESULT __stdcall CClassContainer::QueryInterface(REFIID riid, void * * ppvObject)
  230. {
  231. IUnknown *pUnkTemp = NULL;
  232. SCODE sc = S_OK;
  233. if( IsEqualIID( IID_IUnknown, riid ) )
  234. {
  235. pUnkTemp = (IUnknown *)(IClassAdmin *)this;
  236. }
  237. else if( IsEqualIID( IID_IClassAdmin, riid ) )
  238. {
  239. pUnkTemp = (IUnknown *)(IClassAdmin *)this;
  240. }
  241. else if( IsEqualIID( IID_ICatRegister, riid ) )
  242. {
  243. pUnkTemp = (IUnknown *)(ICatRegister *)this;
  244. }
  245. else if( IsEqualIID( IID_ICatInformation, riid ) )
  246. {
  247. pUnkTemp = (IUnknown *)(ICatInformation *)this;
  248. }
  249. else {
  250. sc = (E_NOINTERFACE);
  251. }
  252. if((pUnkTemp != NULL) && (SUCCEEDED(sc)))
  253. {
  254. *ppvObject = (void * )pUnkTemp;
  255. pUnkTemp->AddRef();
  256. }
  257. return(sc);
  258. }
  259. ULONG __stdcall CClassContainer::AddRef()
  260. {
  261. InterlockedIncrement(( long * )&m_uRefs );
  262. return m_uRefs;
  263. }
  264. ULONG __stdcall CClassContainer::Release()
  265. {
  266. unsigned long uTmp = InterlockedDecrement((long *)&m_uRefs);
  267. unsigned long cRef = m_uRefs;
  268. if (uTmp == 0)
  269. {
  270. delete this;
  271. }
  272. return(cRef);
  273. }
  274.