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.

142 lines
3.1 KiB

  1. #if !defined(_FUSION_INC_GITCOOKIE_H_INCLUDED_)
  2. #define _FUSION_INC_GITCOOKIE_H_INCLUDED_
  3. #pragma once
  4. #include <objidl.h>
  5. template <class TInterface> class CGITCookie
  6. {
  7. public:
  8. CGITCookie() : m_dwCookie(0), m_fSet(false) { }
  9. ~CGITCookie()
  10. {
  11. HRESULT hr;
  12. IGlobalInterfaceTable *pGIT = NULL;
  13. // In debug builds, always create the GIT. This is slower, but will find code
  14. // paths which are destroying CGITCookie instances after COM is uninitialized
  15. // for the thread.
  16. #if DBG
  17. hr = this->GetGIT(&pGIT);
  18. ASSERT(SUCCEEDED(hr));
  19. if (SUCCEEDED(hr))
  20. {
  21. if (m_fSet)
  22. {
  23. hr = pGIT->RevokeInterfaceFromGlobal(m_dwCookie);
  24. ASSERT(SUCCEEDED(hr));
  25. m_fSet = false;
  26. }
  27. pGIT->Release();
  28. }
  29. #else
  30. if (m_fSet)
  31. {
  32. hr = this->GetGIT(&pGIT);
  33. if (SUCCEEDED(hr))
  34. {
  35. (VOID) pGIT->RevokeInterfaceFromGlobal(m_dwCookie);
  36. }
  37. m_fSet = false;
  38. }
  39. #endif
  40. }
  41. HRESULT Set(TInterface *pt)
  42. {
  43. IGlobalInterfaceTable *pGIT = NULL;
  44. DWORD dwCookieTemp = 0;
  45. bool fTempCookieNeedsToBeFreed = false;
  46. HRESULT hr = this->GetGIT(&pGIT);
  47. if (FAILED(hr))
  48. goto Exit;
  49. if (pt != NULL)
  50. {
  51. hr = pGIT->RegisterInterfaceInGlobal(pt, __uuidof(TInterface), &dwCookieTemp);
  52. if (FAILED(hr))
  53. goto Exit;
  54. fTempCookieNeedsToBeFreed = true;
  55. }
  56. if (m_fSet)
  57. {
  58. hr = pGIT->RevokeInterfaceFromGlobal(m_dwCookie);
  59. if (FAILED(hr))
  60. goto Exit;
  61. m_fSet = false;
  62. }
  63. if (pt != NULL)
  64. {
  65. m_dwCookie = dwCookieTemp;
  66. m_fSet = true;
  67. fTempCookieNeedsToBeFreed = false;
  68. }
  69. hr = NOERROR;
  70. Exit:
  71. if (fTempCookieNeedsToBeFreed)
  72. pGIT->RevokeInterfaceFromGlobal(dwCookieTemp);
  73. return hr;
  74. }
  75. HRESULT Get(TInterface **ppt)
  76. {
  77. HRESULT hr = NOERROR;
  78. IGlobalInterfaceTable *pGIT = NULL;
  79. ASSERT(ppt != NULL);
  80. if (ppt == NULL)
  81. {
  82. hr = E_INVALIDARG;
  83. goto Exit;
  84. }
  85. // How can you get if you haven't set?
  86. ASSERT(m_fSet);
  87. if (!m_fSet)
  88. {
  89. hr = E_UNEXPECTED;
  90. goto Exit;
  91. }
  92. ASSERT((*ppt) == NULL);
  93. hr = this->GetGIT(&pGIT);
  94. if (FAILED(hr))
  95. goto Exit;
  96. hr = pGIT->GetInterfaceFromGlobal(m_dwCookie, __uuidof(TInterface), (LPVOID *) ppt);
  97. if (FAILED(hr))
  98. goto Exit;
  99. hr = NOERROR;
  100. Exit:
  101. if (pGIT != NULL)
  102. pGIT->Release();
  103. return hr;
  104. }
  105. private:
  106. HRESULT GetGIT(IGlobalInterfaceTable **ppGIT)
  107. {
  108. return ::CoCreateInstance(
  109. CLSID_StdGlobalInterfaceTable,
  110. NULL,
  111. CLSCTX_INPROC_SERVER,
  112. IID_IGlobalInterfaceTable,
  113. (LPVOID *) ppGIT);
  114. }
  115. DWORD m_dwCookie;
  116. bool m_fSet;
  117. };
  118. #endif