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.

212 lines
5.8 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: C O N T A I N E R M A N A G E R . C P P
  7. //
  8. // Contents: Manages process isolation support for device host.
  9. //
  10. // Notes:
  11. //
  12. // Author: mbend 11 Sep 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "uhbase.h"
  18. #include "hostp.h"
  19. #include "ContainerManager.h"
  20. #include "uhsync.h"
  21. #include "ComUtility.h"
  22. #include "msftcont.h"
  23. #include "uhcommon.h"
  24. CContainerManager::CContainerManager()
  25. {
  26. }
  27. CContainerManager::~CContainerManager()
  28. {
  29. }
  30. STDMETHODIMP CContainerManager::ReferenceContainer(
  31. /*[in, string]*/ const wchar_t * szContainer)
  32. {
  33. CALock lock(*this);
  34. HRESULT hr = S_OK;
  35. hr = HrIsAllowedCOMCallLocality((CALL_LOCALITY) CALL_LOCALITY_INPROC);
  36. if ( SUCCEEDED( hr ) )
  37. {
  38. // Ignore special container
  39. if(!lstrcmp(c_szUPnPDeviceHostContainer, szContainer))
  40. {
  41. return S_OK;
  42. }
  43. CUString strContainer;
  44. hr = strContainer.HrAssign(szContainer);
  45. if(SUCCEEDED(hr))
  46. {
  47. ContainerInfo * pContainerInfo = NULL;
  48. hr = m_containerTable.HrLookup(strContainer, &pContainerInfo);
  49. if(SUCCEEDED(hr))
  50. {
  51. ++pContainerInfo->m_nRefs;
  52. }
  53. else
  54. {
  55. hr = S_OK;
  56. ContainerInfo containerInfo;
  57. containerInfo.m_nRefs = 1;
  58. hr = containerInfo.m_pContainer.HrCreateInstanceLocal(CLSID_UPnPContainer);
  59. if(SUCCEEDED(hr))
  60. {
  61. hr = m_containerTable.HrInsertTransfer(strContainer, containerInfo);
  62. }
  63. }
  64. }
  65. }
  66. TraceHr(ttidError, FAL, hr, FALSE, "CContainerManager::ReferenceContainer");
  67. return hr;
  68. }
  69. STDMETHODIMP CContainerManager::UnreferenceContainer(
  70. /*[in, string]*/ const wchar_t * szContainer)
  71. {
  72. CALock lock(*this);
  73. HRESULT hr = S_OK;
  74. hr = HrIsAllowedCOMCallLocality((CALL_LOCALITY) CALL_LOCALITY_INPROC);
  75. if ( SUCCEEDED( hr ) )
  76. {
  77. // Ignore special container
  78. if(!lstrcmp(c_szUPnPDeviceHostContainer, szContainer))
  79. {
  80. return S_OK;
  81. }
  82. CUString strContainer;
  83. hr = strContainer.HrAssign(szContainer);
  84. if(SUCCEEDED(hr))
  85. {
  86. ContainerInfo * pContainerInfo = NULL;
  87. hr = m_containerTable.HrLookup(strContainer, &pContainerInfo);
  88. if(SUCCEEDED(hr))
  89. {
  90. --pContainerInfo->m_nRefs;
  91. if(!pContainerInfo->m_nRefs)
  92. {
  93. // No one is using
  94. hr = pContainerInfo->m_pContainer->Shutdown();
  95. pContainerInfo->m_pContainer.Release();
  96. if(SUCCEEDED(hr))
  97. {
  98. hr = m_containerTable.HrErase(strContainer);
  99. }
  100. }
  101. }
  102. }
  103. }
  104. TraceHr(ttidError, FAL, hr, FALSE, "CContainerManager::UnreferenceContainer");
  105. return hr;
  106. }
  107. STDMETHODIMP CContainerManager::CreateInstance(
  108. /*[in, string]*/ const wchar_t * szContainer,
  109. /*[in]*/ REFCLSID clsid,
  110. /*[in]*/ REFIID riid,
  111. /*[out, iid_is(riid)]*/ void ** ppv)
  112. {
  113. CHECK_POINTER(szContainer);
  114. CHECK_POINTER(ppv);
  115. CALock lock(*this);
  116. HRESULT hr = S_OK;
  117. hr = HrIsAllowedCOMCallLocality((CALL_LOCALITY) CALL_LOCALITY_INPROC);
  118. if ( SUCCEEDED( hr ) )
  119. {
  120. // Create inproc for special container
  121. if(!lstrcmp(c_szUPnPDeviceHostContainer, szContainer))
  122. {
  123. hr = HrCoCreateInstanceInprocBase(clsid, riid, ppv);
  124. }
  125. else
  126. {
  127. CUString strContainer;
  128. hr = strContainer.HrAssign(szContainer);
  129. if(SUCCEEDED(hr))
  130. {
  131. ContainerInfo * pContainerInfo = NULL;
  132. hr = m_containerTable.HrLookup(strContainer, &pContainerInfo);
  133. if(SUCCEEDED(hr))
  134. {
  135. hr = pContainerInfo->m_pContainer->CreateInstance(clsid, riid, ppv);
  136. if (SUCCEEDED(hr))
  137. {
  138. hr = pContainerInfo->m_pContainer->SetParent(GetCurrentProcessId());
  139. }
  140. }
  141. }
  142. }
  143. }
  144. TraceHr(ttidError, FAL, hr, FALSE, "CContainerManager::CreateInstance");
  145. return hr;
  146. }
  147. STDMETHODIMP CContainerManager::CreateInstanceWithProgId(
  148. /*[in, string]*/ const wchar_t * szContainer,
  149. /*[in, string]*/ const wchar_t * szProgId,
  150. /*[in]*/ REFIID riid,
  151. /*[out, iid_is(riid)]*/ void ** ppv)
  152. {
  153. CALock lock(*this);
  154. HRESULT hr = S_OK;
  155. CLSID clsid;
  156. hr = HrIsAllowedCOMCallLocality((CALL_LOCALITY) CALL_LOCALITY_INPROC);
  157. if ( SUCCEEDED( hr ) )
  158. {
  159. hr = CLSIDFromProgID(szProgId, &clsid);
  160. if(SUCCEEDED(hr))
  161. {
  162. hr = CreateInstance(szContainer, clsid, riid, ppv);
  163. }
  164. }
  165. TraceHr(ttidError, FAL, hr, FALSE, "CContainerManager::CreateInstanceWithProgId");
  166. return hr;
  167. }
  168. STDMETHODIMP CContainerManager::Shutdown()
  169. {
  170. CALock lock(*this);
  171. HRESULT hr = S_OK;
  172. hr = HrIsAllowedCOMCallLocality((CALL_LOCALITY) CALL_LOCALITY_INPROC);
  173. if ( SUCCEEDED( hr ) )
  174. {
  175. long nCount = m_containerTable.Values().GetCount();
  176. for(long n = 0; n < nCount; ++n)
  177. {
  178. m_containerTable.Values()[n].m_pContainer->Shutdown();
  179. const_cast<IUPnPContainerPtr&>(m_containerTable.Values()[n].m_pContainer).Release();
  180. }
  181. m_containerTable.Clear();
  182. }
  183. TraceHr(ttidError, FAL, hr, FALSE, "CContainerManager::Shutdown");
  184. return hr;
  185. }