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.

208 lines
5.2 KiB

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