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.

209 lines
5.2 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997
  5. //
  6. // File: wbclassf.cxx
  7. //
  8. // Contents: Word Breaker class factory
  9. //
  10. // History: weibz, 10-Sep-1997 created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #include "wbclassf.hxx"
  15. #include "iwbreak.hxx"
  16. extern long gulcInstances;
  17. //+-------------------------------------------------------------------------
  18. //
  19. // Method: CWordBreakerCF::CWordBreakerCF
  20. //
  21. // Synopsis: Word Breaker class factory constructor
  22. //
  23. //--------------------------------------------------------------------------
  24. CWordBreakerCF::CWordBreakerCF( LCID lcid )
  25. : _cRefs( 1 ), _lcid( lcid )
  26. {
  27. InterlockedIncrement( &gulcInstances );
  28. }
  29. //+-------------------------------------------------------------------------
  30. //
  31. // Method: CWordBreakerCF::~CWordBreakerCF
  32. //
  33. // Synopsis: Word Breaker class factory destructor
  34. //
  35. //--------------------------------------------------------------------------
  36. CWordBreakerCF::~CWordBreakerCF()
  37. {
  38. InterlockedDecrement( &gulcInstances );
  39. }
  40. //+-------------------------------------------------------------------------
  41. //
  42. // Method: CWordBreakerCF::QueryInterface
  43. //
  44. // Synopsis: Rebind to other interface
  45. //
  46. // Arguments: [riid] -- IID of new interface
  47. // [ppvObject] -- New interface * returned here
  48. //
  49. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  50. //
  51. //--------------------------------------------------------------------------
  52. SCODE STDMETHODCALLTYPE CWordBreakerCF::QueryInterface( REFIID riid,
  53. void ** ppvObject )
  54. {
  55. // Optimize QueryInterface by only checking minimal number of bytes.
  56. //
  57. // IID_IUnknown = 00000000-0000-0000-C000-000000000046
  58. // IID_IClassFactory = 00000001-0000-0000-C000-000000000046
  59. // --
  60. // |
  61. // +--- Unique!
  62. //
  63. Assert( (IID_IUnknown.Data1& 0x000000FF) == 0x00 );
  64. Assert( (IID_IClassFactory.Data1 & 0x000000FF) == 0x01 );
  65. IUnknown *pUnkTemp;
  66. SCODE sc = S_OK;
  67. switch( riid.Data1 & 0x000000FF ) {
  68. case 0x00:
  69. if ( memcmp( &IID_IUnknown, &riid, sizeof(riid) ) == 0 )
  70. pUnkTemp = (IUnknown *)this;
  71. else
  72. sc = E_NOINTERFACE;
  73. break;
  74. case 0x01:
  75. if ( memcmp( &IID_IClassFactory, &riid, sizeof(riid) ) == 0 )
  76. pUnkTemp = (IUnknown *)(IClassFactory *)this;
  77. else
  78. sc = E_NOINTERFACE;
  79. break;
  80. default:
  81. pUnkTemp = 0;
  82. sc = E_NOINTERFACE;
  83. break;
  84. }
  85. if( 0 != pUnkTemp )
  86. {
  87. *ppvObject = (void * )pUnkTemp;
  88. pUnkTemp->AddRef();
  89. }
  90. else
  91. *ppvObject = 0;
  92. return(sc);
  93. }
  94. //+-------------------------------------------------------------------------
  95. //
  96. // Method: CWordBreakerCF::AddRef
  97. //
  98. // Synopsis: Increments refcount
  99. //
  100. //--------------------------------------------------------------------------
  101. ULONG STDMETHODCALLTYPE CWordBreakerCF::AddRef()
  102. {
  103. return InterlockedIncrement( &_cRefs );
  104. }
  105. //+-------------------------------------------------------------------------
  106. //
  107. // Method: CWordBreakerCF::Release
  108. //
  109. // Synopsis: Decrement refcount. Delete if necessary.
  110. //
  111. //--------------------------------------------------------------------------
  112. ULONG STDMETHODCALLTYPE CWordBreakerCF::Release()
  113. {
  114. unsigned long uTmp = InterlockedDecrement( &_cRefs );
  115. if ( 0 == uTmp )
  116. delete this;
  117. return(uTmp);
  118. }
  119. //+-------------------------------------------------------------------------
  120. //
  121. // Method: CWordBreakerCF::CreateInstance
  122. //
  123. // Synopsis: Creates new CWordBreaker object
  124. //
  125. // Arguments: [pUnkOuter] -- 'Outer' IUnknown
  126. // [riid] -- Interface to bind
  127. // [ppvObject] -- Interface returned here
  128. //
  129. //--------------------------------------------------------------------------
  130. SCODE STDMETHODCALLTYPE
  131. CWordBreakerCF::CreateInstance(
  132. IUnknown * pUnkOuter,
  133. REFIID riid,
  134. void * * ppvObject )
  135. {
  136. CWordBreaker *pIUnk = 0;
  137. SCODE sc = S_OK;
  138. if (NULL != pUnkOuter && !IsEqualIID(riid, IID_IUnknown)) {
  139. return E_NOINTERFACE;
  140. }
  141. __try
  142. {
  143. pIUnk = new CWordBreaker( _lcid );
  144. sc = pIUnk->QueryInterface( riid , ppvObject );
  145. pIUnk->Release(); // Release extra refcount from QueryInterface
  146. }
  147. __except(1)
  148. {
  149. Assert( 0 == pIUnk );
  150. sc = E_UNEXPECTED;
  151. }
  152. return (sc);
  153. }
  154. //+-------------------------------------------------------------------------
  155. //
  156. // Method: CWordBreakerCF::LockServer
  157. //
  158. // Synopsis: Force class factory to remain loaded
  159. //
  160. // Arguments: [fLock] -- TRUE if locking, FALSE if unlocking
  161. //
  162. // Returns: S_OK
  163. //
  164. //--------------------------------------------------------------------------
  165. SCODE STDMETHODCALLTYPE
  166. CWordBreakerCF::LockServer(
  167. BOOL fLock)
  168. {
  169. if(fLock)
  170. InterlockedIncrement( &gulcInstances );
  171. else
  172. InterlockedDecrement( &gulcInstances );
  173. return(S_OK);
  174. }