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.

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