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.

259 lines
7.7 KiB

  1. #include "stdinc.h"
  2. #include "macros.h"
  3. #include "common.h"
  4. #include "idp.h"
  5. #include "sxsutil.h"
  6. #include "fusionbuffer.h"
  7. #include "fusionheap.h"
  8. #define CA_MIGRATE_ASM_CACHE_DIR L"%windir%\\asmcache\\"
  9. HRESULT CA_Migrate_RemoveAssemblyFromAsmCache(CStringBuffer & fullpath)
  10. {
  11. HRESULT hr = S_OK;
  12. IFFAILED_EXIT(ca_SxspDeleteDirectory(fullpath));
  13. Exit:
  14. return hr;
  15. }
  16. HRESULT CA_Migrate_CopyFileToAsmCache(CA_ENM_ASSEMBLY_FILES_CALLBACK_INFO * pInfo)
  17. {
  18. HRESULT hr = S_OK;
  19. CStringBuffer sbFileName;
  20. CStringBuffer sbDestFileName;
  21. PWSTR p = NULL;
  22. PARAMETER_CHECK_NTC(dwFlags == 0);
  23. PARAMETER_CHECK_NTC(pInfo != NULL);
  24. IFFAILED_EXIT(MSI_GetSourceFileFullPathName(CA_FILEFULLPATHNAME_FILENAME_IN_FILE_TABLE,
  25. pInfo->hInstall, pInfo->pszComponentSourceDirectory, pszFileNameInFileTable, sbFileName, NULL));
  26. IFFALSE_EXIT(sbDestFileName.Win32Assign(pInfo->pszAssemblyInAsmCache, wcslen(pInfo->pszAssemblyInAsmCache))); // no trailing slash
  27. p = wcsrchr(sbFileName, L'\\');
  28. INTERNAL_ERROR_CHECK_NTC(p != NULL);
  29. IFFALSE_EXIT(sbDestFileName.Win32Append(p, wcslen(p)));
  30. IFFALSE_EXIT(CopyFileW(sbFileName, sbDestFileName, FALSE));
  31. Exit:
  32. return hr;
  33. }
  34. HRESULT CA_Migrate_AddAssemblyIntoAsmCache(DWORD dwFlags, const CA_ENM_ASSEMBLY_FILES_CALLBACK_INFO * info)
  35. {
  36. HRESULT hr = S_OK;
  37. IFFAILED_EXIT(MSI_EnumComponentFiles(info, CA_Migrate_CopyFileToAsmCache));
  38. Exit:
  39. return hr;
  40. }
  41. HRESULT GetXPInstalledDirectory(MSIHANDLE hInstall, PCWSTR pszComponentID, PWSTR pszAsmDir, DWORD cchbuf)
  42. {
  43. PMSIHANDLE hdb = NULL;
  44. HRESULT hr = S_OK;
  45. WCHAR sqlbuf[CA_MAX_BUF];
  46. PMSIHANDLE hView = NULL;
  47. MSIHANDLE hRecord = NULL;
  48. WCHAR bufName[CA_MAX_BUF];
  49. DWORD cchName;
  50. WCHAR bufValue[CA_MAX_BUF];
  51. DWORD cchValue;
  52. BOOL fWin32, fWin32Policy;
  53. CStringBuffer sbPathBuffer;
  54. UINT iRet;
  55. ASSEMBLY_IDENTITY_ATTRIBUTE Attribute;
  56. PASSEMBLY_IDENTITY AssemblyIdentity = NULL;
  57. PARAMETER_CHECK_NTC(hInstall != NULL);
  58. PARAMETER_CHECK_NTC((pszComponentID != NULL) && (pszAsmDir != NULL));
  59. hdb = MsiGetActiveDatabase(hInstall);
  60. INTERNAL_ERROR_CHECK_NTC( hdb != NULL);
  61. IFFALSE_EXIT(::SxsCreateAssemblyIdentity(0, ASSEMBLY_IDENTITY_TYPE_DEFINITION, &AssemblyIdentity, 0, NULL));
  62. swprintf(sqlbuf, L"SELECT Name, Value FROM MsiAssemblyName WHERE Component_='%s'", pszComponentID);
  63. IF_NOTSUCCESS_SET_HRERR_EXIT(::MsiDatabaseOpenViewW(hdb, sqlbuf, &hView));
  64. IF_NOTSUCCESS_SET_HRERR_EXIT(::MsiViewExecute(hView, 0));
  65. for (;;)
  66. {
  67. //
  68. // for each entry in MsiAssembly Table
  69. //
  70. iRet = MsiViewFetch(hView, &hRecord);
  71. if (iRet == ERROR_NO_MORE_ITEMS)
  72. break;
  73. if (iRet != ERROR_SUCCESS )
  74. SET_HRERR_AND_EXIT(iRet);
  75. cchName = NUMBER_OF(bufName);
  76. cchValue = NUMBER_OF(bufValue);
  77. IF_NOTSUCCESS_SET_HRERR_EXIT(MsiRecordGetStringW(hRecord, 1, bufName, &cchName));
  78. IF_NOTSUCCESS_SET_HRERR_EXIT(MsiRecordGetStringW(hRecord, 2, bufValue, &cchValue));
  79. Attribute.Flags = 0;
  80. Attribute.NamespaceCch = 0;
  81. Attribute.Namespace = NULL;
  82. Attribute.NameCch = cchName;
  83. Attribute.Name = bufName;
  84. Attribute.ValueCch = cchValue;
  85. Attribute.Value = bufValue;
  86. IFFALSE_EXIT(::SxsInsertAssemblyIdentityAttribute(0, AssemblyIdentity, &Attribute));
  87. }
  88. IFFALSE_EXIT(SxsHashAssemblyIdentity(0, AssemblyIdentity, NULL));
  89. //
  90. // generate the path, something like x86_ms-sxstest-sfp_75e377300ab7b886_1.0.0.0_en_04f354da
  91. //
  92. IFFAILED_EXIT(ca_SxspDetermineAssemblyType(AssemblyIdentity, fWin32, fWin32Policy));
  93. IFFAILED_EXIT(ca_SxspGenerateSxsPath(
  94. SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT | (fWin32Policy ? SXSP_GENERATE_SXS_PATH_FLAG_OMIT_VERSION : 0),
  95. SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY,
  96. NULL,
  97. 0,
  98. AssemblyIdentity,
  99. sbPathBuffer));
  100. if (sbPathBuffer.Cch() > cchbuf)
  101. {
  102. SET_HRERR_AND_EXIT(ERROR_INSUFFICIENT_BUFFER);
  103. }
  104. wcscpy(pszAsmDir, sbPathBuffer);
  105. Exit:
  106. SxsDestroyAssemblyIdentity(AssemblyIdentity);
  107. return hr;
  108. }
  109. //
  110. // CA for Fusion Win32 Assembly installation on downlevel(only) :
  111. // copy files into %windir%\asmcache\textual-identity-of-this-assembly\
  112. //
  113. // In order to generate textual-assembly-name,
  114. // be sure to put this CustomAction after MsiAssemblyName table is filled
  115. //
  116. HRESULT __stdcall CA_MigrateDll_Callback(DWORD dwFlags, MSIHANDLE hInstall, PCWSTR pszComponentID, PCWSTR pszManifetFileID)
  117. {
  118. HRESULT hr = S_OK;
  119. WCHAR buf[MAX_PATH];
  120. DWORD cchbuf = NUMBER_OF(buf);
  121. CStringBuffer fullpath;
  122. DWORD dwAttrib;
  123. enum CA_MIGRATION_MSI_INSTALL_MODE fMode;
  124. PMSIHANDLE hdb = NULL;
  125. PARAMETER_CHECK_NTC(dwFlags == 0);
  126. PARAMETER_CHECK_NTC(hInstall != NULL);
  127. PARAMETER_CHECK_NTC(pszComponentID != NULL);
  128. PARAMETER_CHECK_NTC(pszManifetFileID != NULL);
  129. hdb = MsiGetActiveDatabase(hInstall);
  130. INTERNAL_ERROR_CHECK_NTC(hdb != NULL);
  131. UINT iret = ExpandEnvironmentStringsW(CA_MIGRATE_ASM_CACHE_DIR, buf, NUMBER_OF(buf));
  132. if (( iret == 0 ) || (iret > NUMBER_OF(buf)))
  133. {
  134. SET_HRERR_AND_EXIT(::GetLastError());
  135. }
  136. IFFALSE_EXIT(fullpath.Win32Assign(buf, wcslen(buf)));
  137. dwAttrib = GetFileAttributesW(fullpath);
  138. if ( dwAttrib == DWORD(-1) )
  139. {
  140. IFFALSE_EXIT(CreateDirectoryW(fullpath, NULL));
  141. }else
  142. {
  143. ASSERT_NTC(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
  144. INTERNAL_ERROR_CHECK_NTC((dwAttrib & FILE_ATTRIBUTE_DIRECTORY) != 0);
  145. }
  146. //
  147. // based on Attributes&Value in MsiAssemblyName Table to generate "x86_assemblyName_6595b64144ccf1df_6.0.0.0_x-ww_98a51133"
  148. //
  149. IFFAILED_EXIT(GetXPInstalledDirectory(hInstall, pszComponentID, buf, cchbuf));
  150. IFFALSE_EXIT(fullpath.Win32Append(buf, wcslen(buf)));
  151. DWORD dwAttribs = GetFileAttributesW(fullpath);
  152. IFFAILED_EXIT(MSI_GetInstallerState(hInstall, fMode));
  153. if ( fMode == eRemoveProduct)
  154. {
  155. ASSERT_NTC((dwAttribs != 0) && (dwAttribs & FILE_ATTRIBUTE_DIRECTORY));
  156. IFFAILED_EXIT(CA_Migrate_RemoveAssemblyFromAsmCache(fullpath));
  157. }else
  158. {
  159. CA_ENM_ASSEMBLY_FILES_CALLBACK_INFO info ;
  160. ZeroMemory(&info, sizeof(info));
  161. hdb = MsiGetActiveDatabase(hInstall);
  162. IFFAILED_EXIT(MSI_GetComponentSourceDirectory(hInstall, pszComponentID, buf, cchbuf));
  163. info.pszAssemblyInAsmCache = fullpath;
  164. info.pszComponentID = pszComponentID;
  165. info.pszComponentSourceDirectory = buf;
  166. info.hInstall = hInstall;
  167. IFFALSE_EXIT(CreateDirectoryW(fullpath, NULL));
  168. IFFAILED_EXIT(CA_Migrate_AddAssemblyIntoAsmCache(0, &info));
  169. }
  170. Exit:
  171. return hr;
  172. }
  173. HRESULT __stdcall CustomAction_CopyFusionWin32AsmIntoAsmCache(MSIHANDLE hInstall)
  174. {
  175. HRESULT hr = S_OK;
  176. PMSIHANDLE hdb = NULL;
  177. PMSIHANDLE hView = NULL;
  178. MSIHANDLE hRecord = NULL;
  179. #if DBG
  180. MessageBoxA(NULL, "Enjoy the Debug", "ca_migrate", MB_OK);
  181. #endif
  182. hdb = MsiGetActiveDatabase(hInstall);
  183. if ( hdb == 0)
  184. SETFAIL_AND_EXIT;
  185. IFFAILED_EXIT(MSI_EnumWinFuseAssembly(0, hInstall, CA_MigrateDll_Callback));
  186. Exit:
  187. return hr;
  188. }
  189. BOOL WINAPI DllMain(
  190. HINSTANCE hinstDLL,
  191. DWORD fdwReason,
  192. LPVOID lpvReserved
  193. )
  194. {
  195. if (fdwReason == DLL_PROCESS_ATTACH)
  196. {
  197. FusionpInitializeHeap(NULL);
  198. }
  199. return TRUE;
  200. }