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.

86 lines
2.9 KiB

  1. // --------------------------------------------------------------------------------
  2. // Privunk.h
  3. // Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  4. // --------------------------------------------------------------------------------
  5. #include "pch.hxx"
  6. #include "msoert.h"
  7. #include "privunk.h"
  8. // --------------------------------------------------------------------------------
  9. // CPrivateUnknown::CPrivateUnknown
  10. // --------------------------------------------------------------------------------
  11. CPrivateUnknown::CPrivateUnknown(IUnknown *pUnkOuter)
  12. {
  13. m_pUnkOuter = pUnkOuter ? pUnkOuter : &m_cUnkInner;
  14. }
  15. // --------------------------------------------------------------------------------
  16. // CPrivateUnknown::SetOuter
  17. // --------------------------------------------------------------------------------
  18. void CPrivateUnknown::SetOuter(IUnknown *pUnkOuter)
  19. {
  20. // Must have an outer, and should not have been aggregated yet...
  21. Assert(pUnkOuter && m_pUnkOuter == &m_cUnkInner);
  22. // Save pUnkOuter
  23. m_pUnkOuter = pUnkOuter;
  24. }
  25. // --------------------------------------------------------------------------------
  26. // CPrivateUnknown::CUnkInner::QueryInterface
  27. // --------------------------------------------------------------------------------
  28. HRESULT CPrivateUnknown::CUnkInner::QueryInterface(REFIID riid, LPVOID * ppvObj)
  29. {
  30. // I can handle the unknown
  31. if (IsEqualIID(riid, IID_IUnknown))
  32. {
  33. // Return IUnknown
  34. *ppvObj = SAFECAST(this, IUnknown *);
  35. // Increment Ref Count
  36. InterlockedIncrement(&m_cRef);
  37. // Done
  38. return S_OK;
  39. }
  40. // Get my parent (computes the offset of the parent's base address)
  41. CPrivateUnknown *pParent = IToClass(CPrivateUnknown, m_cUnkInner, this);
  42. // Dispatch to PrivateQueryInterface
  43. return pParent->PrivateQueryInterface(riid, ppvObj);
  44. }
  45. // --------------------------------------------------------------------------------
  46. // CPrivateUnknown::CUnkInner::AddRef
  47. // --------------------------------------------------------------------------------
  48. ULONG CPrivateUnknown::CUnkInner::AddRef(void)
  49. {
  50. return InterlockedIncrement(&m_cRef);
  51. }
  52. // --------------------------------------------------------------------------------
  53. // CPrivateUnknown::CUnkInner::Release
  54. // --------------------------------------------------------------------------------
  55. ULONG CPrivateUnknown::CUnkInner::Release(void)
  56. {
  57. // Decrement Internal Reference Count
  58. LONG cRef = InterlockedDecrement(&m_cRef);
  59. // No dead yet...
  60. if (cRef > 0)
  61. return (ULONG)cRef;
  62. // Some groovy, mystical, disco stuff
  63. // protect against cached pointers bumping us up then down
  64. m_cRef = 1000;
  65. // Get the parent
  66. CPrivateUnknown* pParent = IToClass(CPrivateUnknown, m_cUnkInner, this);
  67. // Kill the parent
  68. delete pParent;
  69. // Done
  70. return 0;
  71. }