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.

117 lines
2.8 KiB

  1. /*****************************************************************************
  2. * stdunk.cpp - standard unknown implementation
  3. *****************************************************************************
  4. * Copyright (c) 1997-2000 Microsoft Corporation. All Rights Reserved.
  5. *
  6. */
  7. #include "portcls.h"
  8. #include "stdunk.h"
  9. /*****************************************************************************
  10. * CUnknown implementation
  11. */
  12. /*****************************************************************************
  13. * CUnknown::CUnknown()
  14. *****************************************************************************
  15. * Constructor.
  16. */
  17. CUnknown::CUnknown(PUNKNOWN pUnknownOuter)
  18. : m_lRefCount(0)
  19. {
  20. if (pUnknownOuter)
  21. {
  22. m_pUnknownOuter = pUnknownOuter;
  23. }
  24. else
  25. {
  26. m_pUnknownOuter = PUNKNOWN(dynamic_cast<PNONDELEGATINGUNKNOWN>(this));
  27. }
  28. }
  29. /*****************************************************************************
  30. * CUnknown::~CUnknown()
  31. *****************************************************************************
  32. * Destructor.
  33. */
  34. CUnknown::~CUnknown(void)
  35. {
  36. }
  37. /*****************************************************************************
  38. * INonDelegatingUnknown implementation
  39. */
  40. /*****************************************************************************
  41. * CUnknown::NonDelegatingAddRef()
  42. *****************************************************************************
  43. * Register a new reference to the object without delegating to the outer
  44. * unknown.
  45. */
  46. STDMETHODIMP_(ULONG) CUnknown::NonDelegatingAddRef(void)
  47. {
  48. ASSERT(m_lRefCount >= 0);
  49. InterlockedIncrement(&m_lRefCount);
  50. return ULONG(m_lRefCount);
  51. }
  52. /*****************************************************************************
  53. * CUnknown::NonDelegatingRelease()
  54. *****************************************************************************
  55. * Release a reference to the object without delegating to the outer unknown.
  56. */
  57. STDMETHODIMP_(ULONG) CUnknown::NonDelegatingRelease(void)
  58. {
  59. ASSERT(m_lRefCount > 0);
  60. if (InterlockedDecrement(&m_lRefCount) == 0)
  61. {
  62. m_lRefCount++;
  63. delete this;
  64. return 0;
  65. }
  66. return ULONG(m_lRefCount);
  67. }
  68. /*****************************************************************************
  69. * CUnknown::NonDelegatingQueryInterface()
  70. *****************************************************************************
  71. * Obtains an interface.
  72. */
  73. STDMETHODIMP_(NTSTATUS) CUnknown::NonDelegatingQueryInterface
  74. (
  75. REFIID rIID,
  76. PVOID * ppVoid
  77. )
  78. {
  79. ASSERT(ppVoid);
  80. if (IsEqualGUIDAligned(rIID,IID_IUnknown))
  81. {
  82. *ppVoid = PVOID(PUNKNOWN(this));
  83. }
  84. else
  85. {
  86. *ppVoid = NULL;
  87. }
  88. if (*ppVoid)
  89. {
  90. PUNKNOWN(*ppVoid)->AddRef();
  91. return STATUS_SUCCESS;
  92. }
  93. return STATUS_INVALID_PARAMETER;
  94. }