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.

137 lines
3.6 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: unknown.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. /*----------------------------------------------------------------------------
  11. / Title;
  12. / unknown.cpp
  13. /
  14. / Authors;
  15. / David De Vorchik (daviddv)
  16. /
  17. / Notes;
  18. / Helper functions for handling IUnknown
  19. /----------------------------------------------------------------------------*/
  20. #include "precomp.hxx"
  21. #pragma hdrstop
  22. /*-----------------------------------------------------------------------------
  23. / CUnknown
  24. / Helper functions to aid the implementation of IUnknown within objects,
  25. / handles not only AddRef and Release, but also QueryInterface.
  26. /----------------------------------------------------------------------------*/
  27. LONG g_cRefCount = 0; // global reference count
  28. CUnknown::CUnknown()
  29. {
  30. m_cRefCount = 1;
  31. InterlockedIncrement(&g_cRefCount);
  32. }
  33. CUnknown::~CUnknown()
  34. {
  35. TraceAssert( m_cRefCount == 0 );
  36. InterlockedDecrement(&g_cRefCount);
  37. }
  38. /*-----------------------------------------------------------------------------
  39. / CUnknown::HandleQueryInterface
  40. / ------------------------------
  41. / A table driven implementation of QueryInterface that scans through trying
  42. / to find a suitable match for the object.
  43. /
  44. / In:
  45. / riid = interface being requested
  46. / ppvObject -> receives a pointer to the object
  47. / aIntefaces = array of interface descriptions
  48. / cif = number of interfaces in array
  49. /
  50. / Out:
  51. / -
  52. /----------------------------------------------------------------------------*/
  53. STDMETHODIMP CUnknown::HandleQueryInterface(REFIID riid, LPVOID* ppvObject, LPINTERFACES aInterfaces, int cif)
  54. {
  55. HRESULT hr = S_OK;
  56. int i;
  57. TraceAssert(ppvObject);
  58. TraceAssert(aInterfaces);
  59. TraceAssert(cif);
  60. if (ppvObject)
  61. {
  62. *ppvObject = NULL; // no interface yet
  63. }
  64. for ( i = 0; aInterfaces && ppvObject && (i != cif); i++ )
  65. {
  66. if ( IsEqualIID(riid, *aInterfaces[i].piid) || IsEqualIID(riid, IID_IUnknown) )
  67. {
  68. *ppvObject = aInterfaces[i].pvObject;
  69. goto exit_gracefully;
  70. }
  71. }
  72. hr = E_NOINTERFACE; // failed.
  73. exit_gracefully:
  74. if ( ppvObject && SUCCEEDED(hr) )
  75. ((LPUNKNOWN)*ppvObject)->AddRef();
  76. return hr;
  77. }
  78. /*-----------------------------------------------------------------------------
  79. / CUnknown::HandleAddRef
  80. / ----------------------
  81. / Increase the objects reference count. Global reference count increase
  82. / by the constructor.
  83. /
  84. / In:
  85. / -
  86. / Out:
  87. / current reference count
  88. /----------------------------------------------------------------------------*/
  89. STDMETHODIMP_(ULONG) CUnknown::HandleAddRef()
  90. {
  91. return InterlockedIncrement(&m_cRefCount);
  92. }
  93. /*-----------------------------------------------------------------------------
  94. / CUnknown::HandleRelease
  95. / -----------------------
  96. / Decrease the reference counts, when the objects reaches zero then
  97. / destroy it (which inturn will decrease the global reference count).
  98. /
  99. / In:
  100. / -
  101. / Out:
  102. / current reference count == 0 if destroyed
  103. /----------------------------------------------------------------------------*/
  104. STDMETHODIMP_(ULONG) CUnknown::HandleRelease()
  105. {
  106. ULONG cRefCount;
  107. cRefCount = InterlockedDecrement(&m_cRefCount);
  108. if ( cRefCount )
  109. return cRefCount;
  110. delete this;
  111. return 0;
  112. }