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.

119 lines
2.9 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1999 **
  4. //*********************************************************************
  5. //
  6. // CUNKNOWN.CPP - Implementation of IUnknown
  7. //
  8. // HISTORY:
  9. //
  10. // 1/27/99 a-jaswed Created.
  11. //
  12. // IUnknown Base class
  13. #include "cunknown.h"
  14. #include "cfactory.h"
  15. #include "util.h"
  16. ///////////////////////////////////////////////////////////
  17. // Count of active objects. Use to determine if we can unload the DLL.
  18. //
  19. long CUnknown::s_cActiveComponents = 0;
  20. ///////////////////////////////////////////////////////////
  21. // Constructor
  22. //
  23. CUnknown::CUnknown(IUnknown* pOuterUnknown)
  24. : m_cRef(1)
  25. {
  26. // Set pOuterUnknown pointer.
  27. if (pOuterUnknown == NULL)
  28. {
  29. TRACE(L"CUnknown: Using nondelegating IUnknown.") ;
  30. m_pOuterUnknown = reinterpret_cast<IUnknown*>(static_cast<INondelegatingUnknown*>(this)) ; // notice cast
  31. }
  32. else
  33. {
  34. TRACE(L"CUnknown: Aggregating. Using delegating IUnknown.") ;
  35. m_pOuterUnknown = pOuterUnknown;
  36. }
  37. // Increment count of active components.
  38. ::InterlockedIncrement(&s_cActiveComponents) ;
  39. }
  40. ///////////////////////////////////////////////////////////
  41. // Destructor
  42. //
  43. CUnknown::~CUnknown()
  44. {
  45. ::InterlockedDecrement(&s_cActiveComponents) ;
  46. // If this is an exe server shut it down.
  47. CFactory::CloseExe(); //@local server
  48. }
  49. ///////////////////////////////////////////////////////////
  50. // FinalRelease -- called by Release before it deletes the component.
  51. //
  52. void CUnknown::FinalRelease()
  53. {
  54. TRACE(L"FinalRelease\n") ;
  55. m_cRef = 1;
  56. }
  57. ///////////////////////////////////////////////////////////
  58. // NonDelegatingIUnknown - Override to handle custom interfaces.
  59. //
  60. HRESULT __stdcall
  61. CUnknown::NondelegatingQueryInterface(const IID& riid, void** ppv)
  62. {
  63. // CUnknown only supports IUnknown.
  64. if (riid == IID_IUnknown)
  65. {
  66. return FinishQI(reinterpret_cast<IUnknown*>(static_cast<INondelegatingUnknown*>(this)), ppv) ;
  67. }
  68. else
  69. {
  70. *ppv = NULL ;
  71. return E_NOINTERFACE ;
  72. }
  73. }
  74. ///////////////////////////////////////////////////////////
  75. //
  76. // AddRef
  77. //
  78. ULONG __stdcall CUnknown::NondelegatingAddRef()
  79. {
  80. return ::InterlockedIncrement(&m_cRef) ;
  81. }
  82. ///////////////////////////////////////////////////////////
  83. //
  84. // Release
  85. //
  86. ULONG __stdcall CUnknown::NondelegatingRelease()
  87. {
  88. ::InterlockedDecrement(&m_cRef) ;
  89. if (m_cRef == 0)
  90. {
  91. FinalRelease() ;
  92. delete this ;
  93. return 0 ;
  94. }
  95. return m_cRef;
  96. }
  97. ///////////////////////////////////////////////////////////
  98. // FinishQI -
  99. //
  100. // Helper function to simplify overriding NondelegatingQueryInterface
  101. //
  102. HRESULT CUnknown::FinishQI(IUnknown* pI, void** ppv)
  103. {
  104. // Copy pointer into out parameter.
  105. *ppv = pI ;
  106. // Increment reference count for this interface.
  107. pI->AddRef() ;
  108. return S_OK ;
  109. }