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.

443 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000
  5. //
  6. // File: cxxifilt.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. long gulcInstances = 0;
  17. extern "C" CLSID TYPID_CxxIFilter = {
  18. 0x96fe75e0,
  19. 0xa581,
  20. 0x101a,
  21. { 0xb5, 0x53, 0x08, 0x00, 0x2b, 0x33, 0xb0, 0xe6 }
  22. };
  23. extern "C" CLSID CLSID_CxxIFilter = {
  24. 0xC1BCD320,
  25. 0xBF96,
  26. 0x11CD,
  27. { 0xB5, 0x79, 0x08, 0x00, 0x2B, 0x30, 0xBF, 0xEB }
  28. };
  29. extern "C" CLSID CLSID_CxxClass = {
  30. 0x96fe75e1,
  31. 0xa581,
  32. 0x101a,
  33. { 0xb5, 0x53, 0x08, 0x00, 0x2b, 0x33, 0xb0, 0xe6 }
  34. };
  35. //+-------------------------------------------------------------------------
  36. //
  37. // Method: CxxIFilterBase::CxxIFilterBase
  38. //
  39. // Synopsis: Base constructor
  40. //
  41. // Effects: Manages global refcount
  42. //
  43. // History: 23-Feb-1994 KyleP Created
  44. //
  45. //--------------------------------------------------------------------------
  46. CxxIFilterBase::CxxIFilterBase()
  47. {
  48. _uRefs = 1;
  49. InterlockedIncrement( &gulcInstances );
  50. }
  51. //+-------------------------------------------------------------------------
  52. //
  53. // Method: CxxIFilterBase::~CxxIFilterBase
  54. //
  55. // Synopsis: Base destructor
  56. //
  57. // Effects: Manages global refcount
  58. //
  59. // History: 23-Feb-1994 KyleP Created
  60. //
  61. //--------------------------------------------------------------------------
  62. CxxIFilterBase::~CxxIFilterBase()
  63. {
  64. InterlockedDecrement( &gulcInstances );
  65. }
  66. //+-------------------------------------------------------------------------
  67. //
  68. // Method: CxxIFilterBase::QueryInterface
  69. //
  70. // Synopsis: Rebind to other interface
  71. //
  72. // Arguments: [riid] -- IID of new interface
  73. // [ppvObject] -- New interface * returned here
  74. //
  75. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  76. //
  77. // History: 23-Feb-1994 KyleP Created
  78. //
  79. //--------------------------------------------------------------------------
  80. SCODE STDMETHODCALLTYPE CxxIFilterBase::QueryInterface( REFIID riid,
  81. void ** ppvObject)
  82. {
  83. SCODE sc = S_OK;
  84. if ( 0 == ppvObject )
  85. return E_INVALIDARG;
  86. *ppvObject = 0;
  87. if ( IID_IFilter == riid )
  88. *ppvObject = (IUnknown *)(IFilter *)this;
  89. else if ( IID_IPersist == riid )
  90. *ppvObject = (IUnknown *)(IPersist *)(IPersistFile *)this;
  91. else if ( IID_IPersistFile == riid )
  92. *ppvObject = (IUnknown *)(IPersistFile *)this;
  93. else if ( IID_IUnknown == riid )
  94. *ppvObject = (IUnknown *)(IPersist *)(IPersistFile *)this;
  95. else
  96. sc = E_NOINTERFACE;
  97. if ( SUCCEEDED( sc ) )
  98. AddRef();
  99. return sc;
  100. } //QueryInterface
  101. //+-------------------------------------------------------------------------
  102. //
  103. // Method: CxxIFilterBase::AddRef
  104. //
  105. // Synopsis: Increments refcount
  106. //
  107. // History: 23-Feb-1994 KyleP Created
  108. //
  109. //--------------------------------------------------------------------------
  110. ULONG STDMETHODCALLTYPE CxxIFilterBase::AddRef()
  111. {
  112. return InterlockedIncrement( &_uRefs );
  113. }
  114. //+-------------------------------------------------------------------------
  115. //
  116. // Method: CxxIFilterBase::Release
  117. //
  118. // Synopsis: Decrement refcount. Delete if necessary.
  119. //
  120. // History: 23-Feb-1994 KyleP Created
  121. //
  122. //--------------------------------------------------------------------------
  123. ULONG STDMETHODCALLTYPE CxxIFilterBase::Release()
  124. {
  125. unsigned long uTmp = InterlockedDecrement( &_uRefs );
  126. if ( 0 == uTmp )
  127. delete this;
  128. return(uTmp);
  129. }
  130. //+-------------------------------------------------------------------------
  131. //
  132. // Method: CxxIFilterCF::CxxIFilterCF
  133. //
  134. // Synopsis: Text IFilter class factory constructor
  135. //
  136. // History: 23-Feb-1994 KyleP Created
  137. //
  138. //--------------------------------------------------------------------------
  139. CxxIFilterCF::CxxIFilterCF()
  140. {
  141. _uRefs = 1;
  142. long c = InterlockedIncrement( &gulcInstances );
  143. }
  144. //+-------------------------------------------------------------------------
  145. //
  146. // Method: CxxIFilterCF::~CxxIFilterCF
  147. //
  148. // Synopsis: Text IFilter class factory constructor
  149. //
  150. // History: 23-Feb-1994 KyleP Created
  151. //
  152. //--------------------------------------------------------------------------
  153. CxxIFilterCF::~CxxIFilterCF()
  154. {
  155. long c = InterlockedDecrement( &gulcInstances );
  156. }
  157. //+-------------------------------------------------------------------------
  158. //
  159. // Method: CxxIFilterCF::QueryInterface
  160. //
  161. // Synopsis: Rebind to other interface
  162. //
  163. // Arguments: [riid] -- IID of new interface
  164. // [ppvObject] -- New interface * returned here
  165. //
  166. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  167. //
  168. // History: 23-Feb-1994 KyleP Created
  169. //
  170. //--------------------------------------------------------------------------
  171. SCODE STDMETHODCALLTYPE CxxIFilterCF::QueryInterface( REFIID riid,
  172. void ** ppvObject )
  173. {
  174. SCODE sc = S_OK;
  175. if ( 0 == ppvObject )
  176. return E_INVALIDARG;
  177. *ppvObject = 0;
  178. if ( IID_IClassFactory == riid )
  179. *ppvObject = (IUnknown *)(IClassFactory *)this;
  180. else if ( IID_ITypeLib == riid )
  181. sc = E_NOTIMPL;
  182. else if ( IID_IUnknown == riid )
  183. *ppvObject = (IUnknown *)(IClassFactory *)this;
  184. else
  185. sc = E_NOINTERFACE;
  186. if ( SUCCEEDED( sc ) )
  187. AddRef();
  188. return sc;
  189. } //QueryInterface
  190. //+-------------------------------------------------------------------------
  191. //
  192. // Method: CxxIFilterCF::AddRef
  193. //
  194. // Synopsis: Increments refcount
  195. //
  196. // History: 23-Feb-1994 KyleP Created
  197. //
  198. //--------------------------------------------------------------------------
  199. ULONG STDMETHODCALLTYPE CxxIFilterCF::AddRef()
  200. {
  201. return InterlockedIncrement( &_uRefs );
  202. }
  203. //+-------------------------------------------------------------------------
  204. //
  205. // Method: CxxIFilterCF::Release
  206. //
  207. // Synopsis: Decrement refcount. Delete if necessary.
  208. //
  209. // History: 23-Feb-1994 KyleP Created
  210. //
  211. //--------------------------------------------------------------------------
  212. ULONG STDMETHODCALLTYPE CxxIFilterCF::Release()
  213. {
  214. unsigned long uTmp = InterlockedDecrement( &_uRefs );
  215. if ( 0 == uTmp )
  216. delete this;
  217. return(uTmp);
  218. }
  219. //+-------------------------------------------------------------------------
  220. //
  221. // Method: CxxIFilterCF::CreateInstance
  222. //
  223. // Synopsis: Creates new TextIFilter object
  224. //
  225. // Arguments: [pUnkOuter] -- 'Outer' IUnknown
  226. // [riid] -- Interface to bind
  227. // [ppvObject] -- Interface returned here
  228. //
  229. // History: 23-Feb-1994 KyleP Created
  230. //
  231. //--------------------------------------------------------------------------
  232. SCODE STDMETHODCALLTYPE CxxIFilterCF::CreateInstance( IUnknown * pUnkOuter,
  233. REFIID riid,
  234. void * * ppvObject )
  235. {
  236. CxxIFilter * pIUnk = 0;
  237. SCODE sc = S_OK;
  238. CTranslateSystemExceptions translate;
  239. TRY
  240. {
  241. pIUnk = new CxxIFilter();
  242. sc = pIUnk->QueryInterface( riid , ppvObject );
  243. if( SUCCEEDED(sc) )
  244. pIUnk->Release(); // Release extra refcount from QueryInterface
  245. }
  246. CATCH(CException, e)
  247. {
  248. Win4Assert( 0 == pIUnk );
  249. switch( e.GetErrorCode() )
  250. {
  251. case E_OUTOFMEMORY:
  252. sc = (E_OUTOFMEMORY);
  253. break;
  254. default:
  255. sc = (E_UNEXPECTED);
  256. }
  257. }
  258. END_CATCH;
  259. return (sc);
  260. }
  261. //+-------------------------------------------------------------------------
  262. //
  263. // Method: CxxIFilterCF::LockServer
  264. //
  265. // Synopsis: Force class factory to remain loaded
  266. //
  267. // Arguments: [fLock] -- TRUE if locking, FALSE if unlocking
  268. //
  269. // Returns: S_OK
  270. //
  271. // History: 23-Feb-1994 KyleP Created
  272. //
  273. //--------------------------------------------------------------------------
  274. SCODE STDMETHODCALLTYPE CxxIFilterCF::LockServer(BOOL fLock)
  275. {
  276. if(fLock)
  277. InterlockedIncrement( &gulcInstances );
  278. else
  279. InterlockedDecrement( &gulcInstances );
  280. return(S_OK);
  281. }
  282. //+-------------------------------------------------------------------------
  283. //
  284. // Function: DllGetClassObject
  285. //
  286. // Synopsis: Ole DLL load class routine
  287. //
  288. // Arguments: [cid] -- Class to load
  289. // [iid] -- Interface to bind to on class object
  290. // [ppvObj] -- Interface pointer returned here
  291. //
  292. // Returns: Text filter class factory
  293. //
  294. // History: 23-Feb-1994 KyleP Created
  295. //
  296. //--------------------------------------------------------------------------
  297. extern "C" SCODE STDMETHODCALLTYPE DllGetClassObject( REFCLSID cid,
  298. REFIID iid,
  299. void ** ppvObj )
  300. {
  301. IUnknown * pResult = 0;
  302. SCODE sc = S_OK;
  303. CTranslateSystemExceptions translate;
  304. TRY
  305. {
  306. if ( memcmp( &cid, &CLSID_CxxIFilter, sizeof(cid) ) == 0
  307. || memcmp( &cid, &CLSID_CxxClass, sizeof(cid) ) == 0 )
  308. pResult = (IUnknown *) new CxxIFilterCF;
  309. else
  310. sc = E_NOINTERFACE;
  311. if( pResult )
  312. {
  313. sc = pResult->QueryInterface( iid, ppvObj );
  314. pResult->Release(); // Release extra refcount from QueryInterface
  315. }
  316. }
  317. CATCH(CException, e)
  318. {
  319. if ( pResult )
  320. pResult->Release();
  321. switch( e.GetErrorCode() )
  322. {
  323. case E_OUTOFMEMORY:
  324. sc = (E_OUTOFMEMORY);
  325. break;
  326. default:
  327. sc = (E_UNEXPECTED);
  328. }
  329. }
  330. END_CATCH;
  331. return (sc);
  332. }
  333. //+-------------------------------------------------------------------------
  334. //
  335. // Method: DllCanUnloadNow
  336. //
  337. // Synopsis: Notifies DLL to unload (cleanup global resources)
  338. //
  339. // Returns: S_OK if it is acceptable for caller to unload DLL.
  340. //
  341. // History: 23-Feb-1994 KyleP Created
  342. //
  343. //--------------------------------------------------------------------------
  344. extern "C" SCODE STDMETHODCALLTYPE DllCanUnloadNow( void )
  345. {
  346. if ( 0 == gulcInstances )
  347. return( S_OK );
  348. else
  349. return( S_FALSE );
  350. }
  351. SClassEntry const aCxxClasses[] =
  352. {
  353. { L".cpp", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  354. { L".hpp", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  355. { L".cxx", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  356. { L".hxx", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  357. { L".c", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  358. { L".h", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  359. { L".w", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  360. { L".acf", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  361. { L".idl", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  362. { L".inl", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  363. { L".odl", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  364. };
  365. SHandlerEntry const CxxHandler =
  366. {
  367. L"{5f2cb400-bf96-11cd-b579-08002b30bfeb}",
  368. L"C++ persistent handler",
  369. L"{c1bcd320-bf96-11cd-b579-08002b30bfeb}",
  370. };
  371. SFilterEntry const CxxFilter =
  372. {
  373. L"{c1bcd320-bf96-11cd-b579-08002b30bfeb}",
  374. L"C++ IFilter",
  375. L"cxxflt.dll",
  376. L"Both"
  377. };
  378. DEFINE_DLLREGISTERFILTER( CxxHandler, CxxFilter, aCxxClasses )