unknown.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 3k
Category:

Windows Kernel

Development Platform:

Visual C++

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