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.

322 lines
9.3 KiB

  1. //depot/private/lab01_fusion/base/win32/fusion/dll/whistler/sxsasmitem.cpp#3 - edit change 16520 (text)
  2. /*++
  3. Copyright (c) 2000 Microsoft Corporation
  4. Module Name:
  5. sxsasmitem.cpp
  6. Abstract:
  7. CAssemblyCacheItem implementation for installation
  8. Author:
  9. Xiaoyu Wu (xiaoyuw) April 2000
  10. Revision History:
  11. xiaoyuw 10/26/2000 revise during beta2 code review period
  12. --*/
  13. #include "stdinc.h"
  14. #include "sxsp.h"
  15. #include "fusionbuffer.h"
  16. #include "fusion.h"
  17. #include "sxsasmitem.h"
  18. #include "CAssemblyCacheItemStream.h"
  19. #include "util.h"
  20. #include "fusiontrace.h"
  21. #include "sxsapi.h"
  22. CAssemblyCacheItem::CAssemblyCacheItem() : m_cRef(0),
  23. m_pRunOnceCookie(NULL), m_pInstallCookie(NULL),
  24. m_fCommit(FALSE), m_fManifest(FALSE)
  25. {
  26. }
  27. CAssemblyCacheItem::~CAssemblyCacheItem()
  28. {
  29. CSxsPreserveLastError ple;
  30. ASSERT_NTC(m_cRef == 0);
  31. if (m_pRunOnceCookie)
  32. {
  33. if (!::SxspCancelRunOnceDeleteDirectory(m_pRunOnceCookie))
  34. {
  35. ::FusionpDbgPrintEx(
  36. FUSION_DBG_LEVEL_ERROR,
  37. "SXS.DLL: SxspCancelRunOnceDeleteDirectory returns FALSE, file a BUG\n");
  38. }
  39. }
  40. if (!m_strTempDir.IsEmpty())
  41. {
  42. if (!::SxspDeleteDirectory(m_strTempDir))
  43. {
  44. ::FusionpDbgPrintEx(
  45. FUSION_DBG_LEVEL_ERROR,
  46. "SXS.DLL: SxspDeleteDirectory returns FALSE, file a BUG\n");
  47. }
  48. }
  49. ple.Restore();
  50. }
  51. HRESULT
  52. CAssemblyCacheItem::Initialize()
  53. {
  54. HRESULT hr = NOERROR;
  55. FN_TRACE_HR(hr);
  56. //create temporary directory for this assembly
  57. IFW32FALSE_EXIT(::SxspCreateWinSxsTempDirectory(m_strTempDir, NULL, &m_strUidBuf, NULL));
  58. IFW32FALSE_EXIT(::SxspCreateRunOnceDeleteDirectory(m_strTempDir, &m_strUidBuf, (PVOID *)&m_pRunOnceCookie));
  59. hr = NOERROR;
  60. Exit:
  61. return hr ;
  62. }
  63. // ---------------------------------------------------------------------------
  64. // CAssemblyCacheItem::CreateStream
  65. // ---------------------------------------------------------------------------
  66. STDMETHODIMP CAssemblyCacheItem::CreateStream(
  67. /* [in] */ DWORD dwFlags,
  68. /* [in] */ LPCWSTR pszName,
  69. /* [in] */ DWORD dwFormat,
  70. /* [in] */ DWORD dwFormatFlags,
  71. /* [out] */ IStream** ppStream,
  72. /* [in, optional] */ ULARGE_INTEGER *puliMaxSize) // ????? in or OUT ?????
  73. {
  74. HRESULT hr = NOERROR;
  75. FN_TRACE_HR(hr);
  76. CStringBuffer FullPathFileNameBuf;
  77. CStringBuffer FullPathSubDirBuf;
  78. CSmartRef<CAssemblyCacheItemStream> pStream;
  79. const static WCHAR szTemp[] = L"..";
  80. // The puliMaxSize is intended to be a hint for preallocation of the temporary storage for the stream. We just don't
  81. // use it.
  82. UNUSED(puliMaxSize);
  83. if (ppStream != NULL)
  84. *ppStream = NULL;
  85. ::FusionpDbgPrintEx(
  86. FUSION_DBG_LEVEL_INSTALLATION,
  87. "SXS: %s called with:\n"
  88. " dwFlags = 0x%08lx\n"
  89. " pszName = \"%ls\"\n"
  90. " dwFormat = %lu\n"
  91. " dwFormatFlags = %lu\n"
  92. " ppStream = %p\n"
  93. " puliMaxSize = %p\n",
  94. __FUNCTION__,
  95. dwFlags,
  96. pszName,
  97. dwFormat,
  98. dwFormatFlags,
  99. ppStream,
  100. puliMaxSize);
  101. PARAMETER_CHECK(dwFlags == 0);
  102. PARAMETER_CHECK(pszName != NULL);
  103. PARAMETER_CHECK(ppStream != NULL);
  104. //Darwin should clean their code about this : use _WIN32_ flags only
  105. PARAMETER_CHECK(
  106. (dwFormat == STREAM_FORMAT_COMPLIB_MANIFEST) ||
  107. (dwFormat == STREAM_FORMAT_WIN32_MANIFEST) ||
  108. (dwFormat == STREAM_FORMAT_COMPLIB_MODULE) ||
  109. (dwFormat == STREAM_FORMAT_WIN32_MODULE));
  110. PARAMETER_CHECK(dwFormatFlags == 0);
  111. // It's illegal to have more than one manifest in the assembly...
  112. PARAMETER_CHECK((!m_fManifest) || ((dwFormat != STREAM_FORMAT_COMPLIB_MANIFEST) && (dwFormat != STREAM_FORMAT_WIN32_MANIFEST)));
  113. *ppStream = NULL;
  114. // one and only one manifest stream for each assembly item.....
  115. if ((dwFormat == STREAM_FORMAT_COMPLIB_MANIFEST) || (dwFormat == STREAM_FORMAT_WIN32_MANIFEST))
  116. {
  117. INTERNAL_ERROR_CHECK(m_fManifest == FALSE);
  118. m_fManifest = TRUE;
  119. }
  120. INTERNAL_ERROR_CHECK(m_strTempDir.IsEmpty() == FALSE); // temporary directory must be there !
  121. IFW32FALSE_EXIT(FullPathFileNameBuf.Win32Assign(m_strTempDir));
  122. IFW32FALSE_EXIT(FullPathFileNameBuf.Win32EnsureTrailingPathSeparator());
  123. IFW32FALSE_EXIT(FullPathFileNameBuf.Win32Append(pszName, ::wcslen(pszName)));
  124. // xiaoyuw@ : below wcsstr() is from old code : not sure whether we need do it
  125. // Do not allow path hackery.
  126. // need to validate this will result in a relative path within asmcache dir.
  127. // For now don't allow ".." in path; collapse the path before doing this.
  128. INTERNAL_ERROR_CHECK(wcsstr(pszName, szTemp) == NULL);
  129. // before file-copying, create subdirectory if needed
  130. // check backslash and forword-slash
  131. IFW32FALSE_EXIT(::SxspCreateMultiLevelDirectory(m_strTempDir, pszName));
  132. IFALLOCFAILED_EXIT(pStream = new CAssemblyCacheItemStream);
  133. IFW32FALSE_EXIT(
  134. pStream->OpenForWrite(
  135. FullPathFileNameBuf,
  136. 0,
  137. CREATE_NEW,
  138. FILE_FLAG_SEQUENTIAL_SCAN));
  139. if ((dwFormat == STREAM_FORMAT_COMPLIB_MANIFEST) || (dwFormat == STREAM_FORMAT_WIN32_MANIFEST)) // but should not be set both bits
  140. IFW32FALSE_EXIT(m_strManifestFileName.Win32Assign(FullPathFileNameBuf)); // record manifest filename
  141. *ppStream = pStream.Disown(); // void func
  142. hr = NOERROR;
  143. Exit:
  144. return hr;
  145. }
  146. // ---------------------------------------------------------------------------
  147. // CAssemblyCacheItem::Commit
  148. // ---------------------------------------------------------------------------
  149. STDMETHODIMP CAssemblyCacheItem::Commit(
  150. DWORD dwFlags,
  151. ULONG *pulDisposition
  152. )
  153. {
  154. HRESULT hr = NOERROR;
  155. FN_TRACE_HR(hr);
  156. ULONG ulDisposition;
  157. SXS_INSTALLW Install = { sizeof(Install) };
  158. ::FusionpDbgPrintEx(
  159. FUSION_DBG_LEVEL_INSTALLATION,
  160. "SXS: %s called:\n"
  161. " dwFlags = 0x%08lx\n"
  162. " pulDisposition = %p\n",
  163. __FUNCTION__,
  164. dwFlags,
  165. pulDisposition);
  166. if (pulDisposition)
  167. *pulDisposition = 0;
  168. PARAMETER_CHECK((dwFlags & ~(IASSEMBLYCACHEITEM_COMMIT_FLAG_REFRESH)) == 0);
  169. // check internal error whether it is ready to commit
  170. INTERNAL_ERROR_CHECK(m_fManifest == TRUE);
  171. INTERNAL_ERROR_CHECK(m_strManifestFileName.IsEmpty() == FALSE); //m_pRunOnceCookie here should be NULL...
  172. // commit here
  173. if ((!m_fCommit) || (dwFlags & IASSEMBLYCACHEITEM_COMMIT_FLAG_REFRESH))
  174. {
  175. Install.dwFlags = SXS_INSTALL_FLAG_INSTALLED_BY_DARWIN |
  176. ((dwFlags & IASSEMBLYCACHEITEM_COMMIT_FLAG_REFRESH) ? SXS_INSTALL_FLAG_REPLACE_EXISTING : 0);
  177. if (m_pInstallCookie != NULL)
  178. {
  179. Install.dwFlags |= SXS_INSTALL_FLAG_INSTALL_COOKIE_VALID;
  180. Install.pvInstallCookie = m_pInstallCookie;
  181. }
  182. Install.lpManifestPath = m_strManifestFileName;
  183. IFW32FALSE_EXIT(::SxsInstallW(&Install));
  184. if ((dwFlags & IASSEMBLYCACHEITEM_COMMIT_FLAG_REFRESH) && (m_fCommit))
  185. {
  186. ::FusionpDbgPrintEx(
  187. FUSION_DBG_LEVEL_INSTALLATION,
  188. "SXS: %s - setting disposition to IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_REFRESHED\n",
  189. __FUNCTION__);
  190. ulDisposition = IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_REFRESHED;
  191. }
  192. else
  193. {
  194. ::FusionpDbgPrintEx(
  195. FUSION_DBG_LEVEL_INSTALLATION,
  196. "SXS: %s - setting disposition to IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_INSTALLED\n",
  197. __FUNCTION__);
  198. ulDisposition = IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_INSTALLED;
  199. }
  200. m_fCommit = TRUE; // committed successfully
  201. }
  202. else
  203. {
  204. ::FusionpDbgPrintEx(
  205. FUSION_DBG_LEVEL_INSTALLATION,
  206. "SXS: %s - setting disposition to IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_ALREADY_INSTALLED\n",
  207. __FUNCTION__);
  208. ulDisposition = IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_ALREADY_INSTALLED;
  209. }
  210. if (pulDisposition)
  211. *pulDisposition = ulDisposition;
  212. hr = NOERROR;
  213. Exit :
  214. return hr;
  215. }
  216. // ---------------------------------------------------------------------------
  217. // CAssemblyCacheItem::AbortItem
  218. // ---------------------------------------------------------------------------
  219. STDMETHODIMP CAssemblyCacheItem::AbortItem()
  220. {
  221. ::FusionpDbgPrintEx(
  222. FUSION_DBG_LEVEL_ERROR,
  223. "SXS: %s called; returning E_NOTIMPL\n",
  224. __FUNCTION__);
  225. return E_NOTIMPL;
  226. }
  227. // ---------------------------------------------------------------------------
  228. // CAssemblyCacheItem::QI
  229. // ---------------------------------------------------------------------------
  230. STDMETHODIMP
  231. CAssemblyCacheItem::QueryInterface(REFIID riid, void** ppvObj)
  232. {
  233. if ((riid == IID_IUnknown) ||
  234. (riid == IID_IAssemblyCacheItem))
  235. {
  236. *ppvObj = static_cast<IAssemblyCacheItem*> (this);
  237. AddRef();
  238. return S_OK;
  239. }
  240. else
  241. {
  242. *ppvObj = NULL;
  243. return E_NOINTERFACE;
  244. }
  245. }
  246. // ---------------------------------------------------------------------------
  247. // CAssemblyCacheItem::AddRef
  248. // ---------------------------------------------------------------------------
  249. STDMETHODIMP_(ULONG)
  250. CAssemblyCacheItem::AddRef()
  251. {
  252. return ::SxspInterlockedIncrement (&m_cRef);
  253. }
  254. // ---------------------------------------------------------------------------
  255. // CAssemblyCacheItem::Release
  256. // ---------------------------------------------------------------------------
  257. STDMETHODIMP_(ULONG)
  258. CAssemblyCacheItem::Release()
  259. {
  260. ULONG lRet = ::SxspInterlockedDecrement (&m_cRef);
  261. if (!lRet)
  262. FUSION_DELETE_SINGLETON(this);
  263. return lRet;
  264. }