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.

121 lines
3.3 KiB

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