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.

445 lines
13 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_IPersistStream == riid )
  94. *ppvObject = (IUnknown *)(IPersistStream *)this;
  95. else if ( IID_IUnknown == riid )
  96. *ppvObject = (IUnknown *)(IPersist *)(IPersistFile *)this;
  97. else
  98. sc = E_NOINTERFACE;
  99. if ( SUCCEEDED( sc ) )
  100. AddRef();
  101. return sc;
  102. } //QueryInterface
  103. //+-------------------------------------------------------------------------
  104. //
  105. // Method: CxxIFilterBase::AddRef
  106. //
  107. // Synopsis: Increments refcount
  108. //
  109. // History: 23-Feb-1994 KyleP Created
  110. //
  111. //--------------------------------------------------------------------------
  112. ULONG STDMETHODCALLTYPE CxxIFilterBase::AddRef()
  113. {
  114. return InterlockedIncrement( &_uRefs );
  115. }
  116. //+-------------------------------------------------------------------------
  117. //
  118. // Method: CxxIFilterBase::Release
  119. //
  120. // Synopsis: Decrement refcount. Delete if necessary.
  121. //
  122. // History: 23-Feb-1994 KyleP Created
  123. //
  124. //--------------------------------------------------------------------------
  125. ULONG STDMETHODCALLTYPE CxxIFilterBase::Release()
  126. {
  127. unsigned long uTmp = InterlockedDecrement( &_uRefs );
  128. if ( 0 == uTmp )
  129. delete this;
  130. return(uTmp);
  131. }
  132. //+-------------------------------------------------------------------------
  133. //
  134. // Method: CxxIFilterCF::CxxIFilterCF
  135. //
  136. // Synopsis: Text IFilter class factory constructor
  137. //
  138. // History: 23-Feb-1994 KyleP Created
  139. //
  140. //--------------------------------------------------------------------------
  141. CxxIFilterCF::CxxIFilterCF()
  142. {
  143. _uRefs = 1;
  144. long c = InterlockedIncrement( &gulcInstances );
  145. }
  146. //+-------------------------------------------------------------------------
  147. //
  148. // Method: CxxIFilterCF::~CxxIFilterCF
  149. //
  150. // Synopsis: Text IFilter class factory constructor
  151. //
  152. // History: 23-Feb-1994 KyleP Created
  153. //
  154. //--------------------------------------------------------------------------
  155. CxxIFilterCF::~CxxIFilterCF()
  156. {
  157. long c = InterlockedDecrement( &gulcInstances );
  158. }
  159. //+-------------------------------------------------------------------------
  160. //
  161. // Method: CxxIFilterCF::QueryInterface
  162. //
  163. // Synopsis: Rebind to other interface
  164. //
  165. // Arguments: [riid] -- IID of new interface
  166. // [ppvObject] -- New interface * returned here
  167. //
  168. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  169. //
  170. // History: 23-Feb-1994 KyleP Created
  171. //
  172. //--------------------------------------------------------------------------
  173. SCODE STDMETHODCALLTYPE CxxIFilterCF::QueryInterface( REFIID riid,
  174. void ** ppvObject )
  175. {
  176. SCODE sc = S_OK;
  177. if ( 0 == ppvObject )
  178. return E_INVALIDARG;
  179. *ppvObject = 0;
  180. if ( IID_IClassFactory == riid )
  181. *ppvObject = (IUnknown *)(IClassFactory *)this;
  182. else if ( IID_ITypeLib == riid )
  183. sc = E_NOTIMPL;
  184. else if ( IID_IUnknown == riid )
  185. *ppvObject = (IUnknown *)(IClassFactory *)this;
  186. else
  187. sc = E_NOINTERFACE;
  188. if ( SUCCEEDED( sc ) )
  189. AddRef();
  190. return sc;
  191. } //QueryInterface
  192. //+-------------------------------------------------------------------------
  193. //
  194. // Method: CxxIFilterCF::AddRef
  195. //
  196. // Synopsis: Increments refcount
  197. //
  198. // History: 23-Feb-1994 KyleP Created
  199. //
  200. //--------------------------------------------------------------------------
  201. ULONG STDMETHODCALLTYPE CxxIFilterCF::AddRef()
  202. {
  203. return InterlockedIncrement( &_uRefs );
  204. }
  205. //+-------------------------------------------------------------------------
  206. //
  207. // Method: CxxIFilterCF::Release
  208. //
  209. // Synopsis: Decrement refcount. Delete if necessary.
  210. //
  211. // History: 23-Feb-1994 KyleP Created
  212. //
  213. //--------------------------------------------------------------------------
  214. ULONG STDMETHODCALLTYPE CxxIFilterCF::Release()
  215. {
  216. unsigned long uTmp = InterlockedDecrement( &_uRefs );
  217. if ( 0 == uTmp )
  218. delete this;
  219. return(uTmp);
  220. }
  221. //+-------------------------------------------------------------------------
  222. //
  223. // Method: CxxIFilterCF::CreateInstance
  224. //
  225. // Synopsis: Creates new TextIFilter object
  226. //
  227. // Arguments: [pUnkOuter] -- 'Outer' IUnknown
  228. // [riid] -- Interface to bind
  229. // [ppvObject] -- Interface returned here
  230. //
  231. // History: 23-Feb-1994 KyleP Created
  232. //
  233. //--------------------------------------------------------------------------
  234. SCODE STDMETHODCALLTYPE CxxIFilterCF::CreateInstance( IUnknown * pUnkOuter,
  235. REFIID riid,
  236. void * * ppvObject )
  237. {
  238. CxxIFilter * pIUnk = 0;
  239. SCODE sc = S_OK;
  240. CTranslateSystemExceptions translate;
  241. TRY
  242. {
  243. pIUnk = new CxxIFilter();
  244. sc = pIUnk->QueryInterface( riid , ppvObject );
  245. if( SUCCEEDED(sc) )
  246. pIUnk->Release(); // Release extra refcount from QueryInterface
  247. }
  248. CATCH(CException, e)
  249. {
  250. Win4Assert( 0 == pIUnk );
  251. switch( e.GetErrorCode() )
  252. {
  253. case E_OUTOFMEMORY:
  254. sc = (E_OUTOFMEMORY);
  255. break;
  256. default:
  257. sc = (E_UNEXPECTED);
  258. }
  259. }
  260. END_CATCH;
  261. return (sc);
  262. }
  263. //+-------------------------------------------------------------------------
  264. //
  265. // Method: CxxIFilterCF::LockServer
  266. //
  267. // Synopsis: Force class factory to remain loaded
  268. //
  269. // Arguments: [fLock] -- TRUE if locking, FALSE if unlocking
  270. //
  271. // Returns: S_OK
  272. //
  273. // History: 23-Feb-1994 KyleP Created
  274. //
  275. //--------------------------------------------------------------------------
  276. SCODE STDMETHODCALLTYPE CxxIFilterCF::LockServer(BOOL fLock)
  277. {
  278. if(fLock)
  279. InterlockedIncrement( &gulcInstances );
  280. else
  281. InterlockedDecrement( &gulcInstances );
  282. return(S_OK);
  283. }
  284. //+-------------------------------------------------------------------------
  285. //
  286. // Function: DllGetClassObject
  287. //
  288. // Synopsis: Ole DLL load class routine
  289. //
  290. // Arguments: [cid] -- Class to load
  291. // [iid] -- Interface to bind to on class object
  292. // [ppvObj] -- Interface pointer returned here
  293. //
  294. // Returns: Text filter class factory
  295. //
  296. // History: 23-Feb-1994 KyleP Created
  297. //
  298. //--------------------------------------------------------------------------
  299. extern "C" SCODE STDMETHODCALLTYPE DllGetClassObject( REFCLSID cid,
  300. REFIID iid,
  301. void ** ppvObj )
  302. {
  303. IUnknown * pResult = 0;
  304. SCODE sc = S_OK;
  305. CTranslateSystemExceptions translate;
  306. TRY
  307. {
  308. if ( memcmp( &cid, &CLSID_CxxIFilter, sizeof(cid) ) == 0
  309. || memcmp( &cid, &CLSID_CxxClass, sizeof(cid) ) == 0 )
  310. pResult = (IUnknown *) new CxxIFilterCF;
  311. else
  312. sc = E_NOINTERFACE;
  313. if( pResult )
  314. {
  315. sc = pResult->QueryInterface( iid, ppvObj );
  316. pResult->Release(); // Release extra refcount from QueryInterface
  317. }
  318. }
  319. CATCH(CException, e)
  320. {
  321. if ( pResult )
  322. pResult->Release();
  323. switch( e.GetErrorCode() )
  324. {
  325. case E_OUTOFMEMORY:
  326. sc = (E_OUTOFMEMORY);
  327. break;
  328. default:
  329. sc = (E_UNEXPECTED);
  330. }
  331. }
  332. END_CATCH;
  333. return (sc);
  334. }
  335. //+-------------------------------------------------------------------------
  336. //
  337. // Method: DllCanUnloadNow
  338. //
  339. // Synopsis: Notifies DLL to unload (cleanup global resources)
  340. //
  341. // Returns: S_OK if it is acceptable for caller to unload DLL.
  342. //
  343. // History: 23-Feb-1994 KyleP Created
  344. //
  345. //--------------------------------------------------------------------------
  346. extern "C" SCODE STDMETHODCALLTYPE DllCanUnloadNow( void )
  347. {
  348. if ( 0 == gulcInstances )
  349. return( S_OK );
  350. else
  351. return( S_FALSE );
  352. }
  353. SClassEntry const aCxxClasses[] =
  354. {
  355. { L".cpp", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  356. { L".hpp", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  357. { L".cxx", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  358. { L".hxx", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  359. { L".c", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  360. { L".h", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  361. { L".w", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  362. { L".acf", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  363. { L".idl", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  364. { L".inl", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  365. { L".odl", L"CxxFile", L"Class for C and C++ Files", L"{96fe75e1-a581-101a-b553-08002b33b0e6}", L"Class for C and C++ Files" },
  366. };
  367. SHandlerEntry const CxxHandler =
  368. {
  369. L"{5f2cb400-bf96-11cd-b579-08002b30bfeb}",
  370. L"C++ persistent handler",
  371. L"{c1bcd320-bf96-11cd-b579-08002b30bfeb}",
  372. };
  373. SFilterEntry const CxxFilter =
  374. {
  375. L"{c1bcd320-bf96-11cd-b579-08002b30bfeb}",
  376. L"C++ IFilter",
  377. L"cxxflt.dll",
  378. L"Both"
  379. };
  380. DEFINE_DLLREGISTERFILTER( CxxHandler, CxxFilter, aCxxClasses )