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.

438 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000
  5. //
  6. // File: genifilt.cxx
  7. //
  8. // Contents: C++ filter 'class factory'.
  9. //
  10. // History: 23-Feb-1994 KyleP Created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #pragma hdrstop
  15. #include <filtreg.hxx>
  16. #include "gen.hxx"
  17. #include "genifilt.hxx"
  18. #include "genflt.hxx"
  19. long gulcInstances = 0;
  20. extern "C" CLSID TYPID_GenIFilter = { /* c4aac357-d152-493b-8c39-d08f575be46e */
  21. 0xc4aac357,
  22. 0xd152,
  23. 0x493b,
  24. {0x8c, 0x39, 0xd0, 0x8f, 0x57, 0x5b, 0xe4, 0x6e}
  25. };
  26. extern "C" CLSID CLSID_GenIFilter = { /* d0c093a9-8f6d-4816-aaad-df054aad0cbc */
  27. 0xd0c093a9,
  28. 0x8f6d,
  29. 0x4816,
  30. {0xaa, 0xad, 0xdf, 0x05, 0x4a, 0xad, 0x0c, 0xbc}
  31. };
  32. extern "C" CLSID CLSID_GenClass = { /* 7322e01d-d56f-494b-a8df-4685cc402f59 */
  33. 0x7322e01d,
  34. 0xd56f,
  35. 0x494b,
  36. {0xa8, 0xdf, 0x46, 0x85, 0xcc, 0x40, 0x2f, 0x59}
  37. };
  38. //+-------------------------------------------------------------------------
  39. //
  40. // Method: GenIFilterBase::GenIFilterBase
  41. //
  42. // Synopsis: Base constructor
  43. //
  44. // Effects: Manages global refcount
  45. //
  46. // History: 23-Feb-1994 KyleP Created
  47. //
  48. //--------------------------------------------------------------------------
  49. GenIFilterBase::GenIFilterBase()
  50. {
  51. _uRefs = 1;
  52. InterlockedIncrement( &gulcInstances );
  53. }
  54. //+-------------------------------------------------------------------------
  55. //
  56. // Method: GenIFilterBase::~GenIFilterBase
  57. //
  58. // Synopsis: Base destructor
  59. //
  60. // Effects: Manages global refcount
  61. //
  62. // History: 23-Feb-1994 KyleP Created
  63. //
  64. //--------------------------------------------------------------------------
  65. GenIFilterBase::~GenIFilterBase()
  66. {
  67. InterlockedDecrement( &gulcInstances );
  68. }
  69. //+-------------------------------------------------------------------------
  70. //
  71. // Method: GenIFilterBase::QueryInterface
  72. //
  73. // Synopsis: Rebind to other interface
  74. //
  75. // Arguments: [riid] -- IID of new interface
  76. // [ppvObject] -- New interface * returned here
  77. //
  78. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  79. //
  80. // History: 23-Feb-1994 KyleP Created
  81. //
  82. //--------------------------------------------------------------------------
  83. SCODE STDMETHODCALLTYPE GenIFilterBase::QueryInterface( REFIID riid,
  84. void ** ppvObject)
  85. {
  86. SCODE sc = S_OK;
  87. if ( 0 == ppvObject )
  88. return E_INVALIDARG;
  89. *ppvObject = 0;
  90. if ( IID_IFilter == riid )
  91. *ppvObject = (IUnknown *)(IFilter *)this;
  92. else if ( IID_IPersist == riid )
  93. *ppvObject = (IUnknown *)(IPersist *)(IPersistFile *)this;
  94. else if ( IID_IPersistFile == riid )
  95. *ppvObject = (IUnknown *)(IPersistFile *)this;
  96. else if ( IID_IUnknown == riid )
  97. *ppvObject = (IUnknown *)(IPersist *)(IPersistFile *)this;
  98. else
  99. sc = E_NOINTERFACE;
  100. if ( SUCCEEDED( sc ) )
  101. AddRef();
  102. return sc;
  103. } //QueryInterface
  104. //+-------------------------------------------------------------------------
  105. //
  106. // Method: GenIFilterBase::AddRef
  107. //
  108. // Synopsis: Increments refcount
  109. //
  110. // History: 23-Feb-1994 KyleP Created
  111. //
  112. //--------------------------------------------------------------------------
  113. ULONG STDMETHODCALLTYPE GenIFilterBase::AddRef()
  114. {
  115. return InterlockedIncrement( &_uRefs );
  116. }
  117. //+-------------------------------------------------------------------------
  118. //
  119. // Method: GenIFilterBase::Release
  120. //
  121. // Synopsis: Decrement refcount. Delete if necessary.
  122. //
  123. // History: 23-Feb-1994 KyleP Created
  124. //
  125. //--------------------------------------------------------------------------
  126. ULONG STDMETHODCALLTYPE GenIFilterBase::Release()
  127. {
  128. unsigned long uTmp = InterlockedDecrement( &_uRefs );
  129. if ( 0 == uTmp )
  130. delete this;
  131. return(uTmp);
  132. }
  133. //+-------------------------------------------------------------------------
  134. //
  135. // Method: GenIFilterCF::GenIFilterCF
  136. //
  137. // Synopsis: Text IFilter class factory constructor
  138. //
  139. // History: 23-Feb-1994 KyleP Created
  140. //
  141. //--------------------------------------------------------------------------
  142. GenIFilterCF::GenIFilterCF()
  143. {
  144. _uRefs = 1;
  145. long c = InterlockedIncrement( &gulcInstances );
  146. }
  147. //+-------------------------------------------------------------------------
  148. //
  149. // Method: GenIFilterCF::~GenIFilterCF
  150. //
  151. // Synopsis: Text IFilter class factory constructor
  152. //
  153. // History: 23-Feb-1994 KyleP Created
  154. //
  155. //--------------------------------------------------------------------------
  156. GenIFilterCF::~GenIFilterCF()
  157. {
  158. long c = InterlockedDecrement( &gulcInstances );
  159. }
  160. //+-------------------------------------------------------------------------
  161. //
  162. // Method: GenIFilterCF::QueryInterface
  163. //
  164. // Synopsis: Rebind to other interface
  165. //
  166. // Arguments: [riid] -- IID of new interface
  167. // [ppvObject] -- New interface * returned here
  168. //
  169. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  170. //
  171. // History: 23-Feb-1994 KyleP Created
  172. //
  173. //--------------------------------------------------------------------------
  174. SCODE STDMETHODCALLTYPE GenIFilterCF::QueryInterface( REFIID riid,
  175. void ** ppvObject )
  176. {
  177. SCODE sc = S_OK;
  178. if ( 0 == ppvObject )
  179. return E_INVALIDARG;
  180. *ppvObject = 0;
  181. if ( IID_IClassFactory == riid )
  182. *ppvObject = (IUnknown *)(IClassFactory *)this;
  183. else if ( IID_ITypeLib == riid )
  184. sc = E_NOTIMPL;
  185. else if ( IID_IUnknown == riid )
  186. *ppvObject = (IUnknown *)(IClassFactory *)this;
  187. else
  188. sc = E_NOINTERFACE;
  189. if ( SUCCEEDED( sc ) )
  190. AddRef();
  191. return sc;
  192. } //QueryInterface
  193. //+-------------------------------------------------------------------------
  194. //
  195. // Method: GenIFilterCF::AddRef
  196. //
  197. // Synopsis: Increments refcount
  198. //
  199. // History: 23-Feb-1994 KyleP Created
  200. //
  201. //--------------------------------------------------------------------------
  202. ULONG STDMETHODCALLTYPE GenIFilterCF::AddRef()
  203. {
  204. return InterlockedIncrement( &_uRefs );
  205. }
  206. //+-------------------------------------------------------------------------
  207. //
  208. // Method: GenIFilterCF::Release
  209. //
  210. // Synopsis: Decrement refcount. Delete if necessary.
  211. //
  212. // History: 23-Feb-1994 KyleP Created
  213. //
  214. //--------------------------------------------------------------------------
  215. ULONG STDMETHODCALLTYPE GenIFilterCF::Release()
  216. {
  217. unsigned long uTmp = InterlockedDecrement( &_uRefs );
  218. if ( 0 == uTmp )
  219. delete this;
  220. return(uTmp);
  221. }
  222. //+-------------------------------------------------------------------------
  223. //
  224. // Method: GenIFilterCF::CreateInstance
  225. //
  226. // Synopsis: Creates new TextIFilter object
  227. //
  228. // Arguments: [pUnkOuter] -- 'Outer' IUnknown
  229. // [riid] -- Interface to bind
  230. // [ppvObject] -- Interface returned here
  231. //
  232. // History: 23-Feb-1994 KyleP Created
  233. //
  234. //--------------------------------------------------------------------------
  235. SCODE STDMETHODCALLTYPE GenIFilterCF::CreateInstance( IUnknown * pUnkOuter,
  236. REFIID riid,
  237. void * * ppvObject )
  238. {
  239. GenIFilter * pIUnk = 0;
  240. SCODE sc = S_OK;
  241. CTranslateSystemExceptions translate;
  242. TRY
  243. {
  244. pIUnk = new GenIFilter();
  245. sc = pIUnk->QueryInterface( riid , ppvObject );
  246. if( SUCCEEDED(sc) )
  247. pIUnk->Release(); // Release extra refcount from QueryInterface
  248. }
  249. CATCH(CException, e)
  250. {
  251. Win4Assert( 0 == pIUnk );
  252. switch( e.GetErrorCode() )
  253. {
  254. case E_OUTOFMEMORY:
  255. sc = (E_OUTOFMEMORY);
  256. break;
  257. default:
  258. sc = (E_UNEXPECTED);
  259. }
  260. }
  261. END_CATCH;
  262. return (sc);
  263. }
  264. //+-------------------------------------------------------------------------
  265. //
  266. // Method: GenIFilterCF::LockServer
  267. //
  268. // Synopsis: Force class factory to remain loaded
  269. //
  270. // Arguments: [fLock] -- TRUE if locking, FALSE if unlocking
  271. //
  272. // Returns: S_OK
  273. //
  274. // History: 23-Feb-1994 KyleP Created
  275. //
  276. //--------------------------------------------------------------------------
  277. SCODE STDMETHODCALLTYPE GenIFilterCF::LockServer(BOOL fLock)
  278. {
  279. if(fLock)
  280. InterlockedIncrement( &gulcInstances );
  281. else
  282. InterlockedDecrement( &gulcInstances );
  283. return(S_OK);
  284. }
  285. //+-------------------------------------------------------------------------
  286. //
  287. // Function: DllGetClassObject
  288. //
  289. // Synopsis: Ole DLL load class routine
  290. //
  291. // Arguments: [cid] -- Class to load
  292. // [iid] -- Interface to bind to on class object
  293. // [ppvObj] -- Interface pointer returned here
  294. //
  295. // Returns: Text filter class factory
  296. //
  297. // History: 23-Feb-1994 KyleP Created
  298. //
  299. //--------------------------------------------------------------------------
  300. extern "C" SCODE STDMETHODCALLTYPE DllGetClassObject( REFCLSID cid,
  301. REFIID iid,
  302. void ** ppvObj )
  303. {
  304. IUnknown * pResult = 0;
  305. SCODE sc = S_OK;
  306. CTranslateSystemExceptions translate;
  307. TRY
  308. {
  309. if ( memcmp( &cid, &CLSID_GenIFilter, sizeof(cid) ) == 0
  310. || memcmp( &cid, &CLSID_GenClass, sizeof(cid) ) == 0 )
  311. pResult = (IUnknown *) new GenIFilterCF;
  312. else
  313. sc = E_NOINTERFACE;
  314. if( pResult )
  315. {
  316. sc = pResult->QueryInterface( iid, ppvObj );
  317. pResult->Release(); // Release extra refcount from QueryInterface
  318. }
  319. }
  320. CATCH(CException, e)
  321. {
  322. if ( pResult )
  323. pResult->Release();
  324. switch( e.GetErrorCode() )
  325. {
  326. case E_OUTOFMEMORY:
  327. sc = (E_OUTOFMEMORY);
  328. break;
  329. default:
  330. sc = (E_UNEXPECTED);
  331. }
  332. }
  333. END_CATCH;
  334. return (sc);
  335. }
  336. //+-------------------------------------------------------------------------
  337. //
  338. // Method: DllCanUnloadNow
  339. //
  340. // Synopsis: Notifies DLL to unload (cleanup global resources)
  341. //
  342. // Returns: S_OK if it is acceptable for caller to unload DLL.
  343. //
  344. // History: 23-Feb-1994 KyleP Created
  345. //
  346. //--------------------------------------------------------------------------
  347. extern "C" SCODE STDMETHODCALLTYPE DllCanUnloadNow( void )
  348. {
  349. if ( 0 == gulcInstances )
  350. return( S_OK );
  351. else
  352. return( S_FALSE );
  353. }
  354. SClassEntry const aGenClasses[] =
  355. {
  356. { L".el", L"GenFile", L"Class for generic files", L"{7322e01d-d56f-494b-a8df-4685cc402f59}", L"Class for generic files" },
  357. // { L".pl", L"GenFile", L"Class for generic files", L"{7322e01d-d56f-494b-a8df-4685cc402f59}", L"Class for generic files" },
  358. // { L".pm", L"GenFile", L"Class for generic files", L"{7322e01d-d56f-494b-a8df-4685cc402f59}", L"Class for generic files" },
  359. };
  360. SHandlerEntry const GenHandler =
  361. {
  362. L"{f7a89b42-365d-4f41-b480-f210a449410e}",
  363. L"Generic persistent handler",
  364. L"{d0c093a9-8f6d-4816-aaad-df054aad0cbc}",
  365. };
  366. SFilterEntry const GenFilter =
  367. {
  368. L"{d0c093a9-8f6d-4816-aaad-df054aad0cbc}",
  369. L"Generic IFilter",
  370. L"genflt.dll",
  371. L"Both"
  372. };
  373. DEFINE_DLLREGISTERFILTER( GenHandler, GenFilter, aGenClasses )