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.

228 lines
6.3 KiB

  1. #include "stdinc.h"
  2. #include <windows.h>
  3. #include "sxsp.h"
  4. #include <stdio.h>
  5. #include <setupapi.h>
  6. #include "fusionhandle.h"
  7. #include "sxspath.h"
  8. #include "sxsapi.h"
  9. #include "sxsid.h"
  10. #include "sxsidp.h"
  11. #include "strongname.h"
  12. #include "fusiontrace.h"
  13. BOOL
  14. SxspCopyFile(
  15. DWORD dwFlags,
  16. PCWSTR pszSource,
  17. PCWSTR pszDestination
  18. )
  19. {
  20. BOOL fSuccess = FALSE;
  21. FN_TRACE_WIN32(fSuccess);
  22. BOOL fFileWasInUse = FALSE;
  23. DWORD dwCopyStyle = 0;
  24. PARAMETER_CHECK((dwFlags & ~(SXSP_COPY_FILE_FLAG_REPLACE_EXISTING | SXSP_COPY_FILE_FLAG_COMPRESSION_AWARE)) == 0);
  25. PARAMETER_CHECK(pszSource != NULL);
  26. PARAMETER_CHECK(pszDestination != NULL);
  27. #if 0
  28. if (dwFlags & SXSP_COPY_FILE_FLAG_COMPRESSION_AWARE)
  29. {
  30. CSmallStringBuffer buffTempFile;
  31. BOOL fTemp;
  32. IFW32FALSE_EXIT(buffTempFile.Win32Assign(pszDestination, wcslen(pszDestination)));
  33. IFW32FALSE_EXIT(buffTempFile.Win32Append(L".$$$", 4));
  34. dwCopyStyle |= SP_COPY_SOURCE_ABSOLUTE | SP_COPY_NOSKIP;
  35. if ((dwFlags & SXSP_COPY_FILE_FLAG_REPLACE_EXISTING) == 0)
  36. dwCopyStyle |= SP_COPY_FORCE_NOOVERWRITE;
  37. IFW32FALSE_ORIGINATE_AND_EXIT(
  38. ::SetupInstallFileExW(
  39. NULL, // optional HINF InfHandle
  40. NULL, // optional PINFCONTEXT InfContext
  41. pszSource, // source file
  42. NULL, // source path
  43. buffTempFile, // optional filename after copy
  44. dwCopyStyle,
  45. NULL, // optional copy msg handler
  46. NULL, // optional copy msg handler context
  47. &fFileWasInUse));
  48. fTemp = ::MoveFileExW(
  49. buffTempFile,
  50. pszDestination,
  51. (dwFlags & SXSP_COPY_FILE_FLAG_REPLACE_EXISTING) ?
  52. MOVEFILE_REPLACE_EXISTING : 0);
  53. if (!fTemp)
  54. {
  55. const DWORD dwLastError = ::FusionpGetLastWin32Error();
  56. fTemp = ::DeleteFileW(buffTempFile);
  57. if (!fTemp)
  58. {
  59. // Oh boy, cleaning up the temporary file didn't work. Queue the deletion...
  60. fTemp = ::MoveFileExW(buffTempFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
  61. // The worst case scenario here is that we have an extra file left around... forget it.
  62. }
  63. ORIGINATE_WIN32_FAILURE_AND_EXIT(MoveFileExW, dwLastError);
  64. }
  65. }
  66. else
  67. #endif
  68. {
  69. IFW32FALSE_ORIGINATE_AND_EXIT(
  70. ::CopyFileW(
  71. pszSource,
  72. pszDestination,
  73. (dwFlags & SXSP_COPY_FILE_FLAG_REPLACE_EXISTING) == 0));
  74. }
  75. fSuccess = TRUE;
  76. Exit:
  77. return fSuccess;
  78. }
  79. BOOL
  80. SxspGetFileSize(
  81. DWORD dwFlags,
  82. PCWSTR file,
  83. ULONGLONG &fileSize
  84. )
  85. {
  86. BOOL fSuccess = FALSE;
  87. FN_TRACE_WIN32(fSuccess);
  88. PWSTR pszActualSource = NULL;
  89. fileSize = 0;
  90. PARAMETER_CHECK(file != NULL);
  91. PARAMETER_CHECK((dwFlags & ~(SXSP_GET_FILE_SIZE_FLAG_COMPRESSION_AWARE | SXSP_GET_FILE_SIZE_FLAG_GET_COMPRESSED_SOURCE_SIZE)) == 0);
  92. PARAMETER_CHECK((dwFlags & SXSP_GET_FILE_SIZE_FLAG_COMPRESSION_AWARE) || !(dwFlags & SXSP_GET_FILE_SIZE_FLAG_GET_COMPRESSED_SOURCE_SIZE));
  93. if (dwFlags & SXSP_GET_FILE_SIZE_FLAG_COMPRESSION_AWARE)
  94. {
  95. DWORD dwTemp;
  96. DWORD dwSourceFileSize, dwTargetFileSize;
  97. UINT uiCompressionType;
  98. dwTemp = ::SetupGetFileCompressionInfoW(
  99. file,
  100. &pszActualSource,
  101. &dwSourceFileSize,
  102. &dwTargetFileSize,
  103. &uiCompressionType);
  104. if (dwTemp != ERROR_SUCCESS)
  105. ORIGINATE_WIN32_FAILURE_AND_EXIT(SetupGetFileCompressionInfoW, dwTemp);
  106. if (pszActualSource != NULL)
  107. ::LocalFree((HLOCAL) pszActualSource);
  108. pszActualSource = NULL;
  109. if (dwFlags & SXSP_GET_FILE_SIZE_FLAG_GET_COMPRESSED_SOURCE_SIZE)
  110. fileSize = dwSourceFileSize;
  111. else
  112. fileSize = dwTargetFileSize;
  113. }
  114. else
  115. {
  116. LARGE_INTEGER liFileSize = {0};
  117. WIN32_FILE_ATTRIBUTE_DATA wfad;
  118. wfad.nFileSizeLow = 0;
  119. wfad.nFileSizeHigh = 0;
  120. IFW32FALSE_ORIGINATE_AND_EXIT(::GetFileAttributesExW(file, GetFileExInfoStandard, &wfad));
  121. liFileSize.LowPart = wfad.nFileSizeLow;
  122. liFileSize.HighPart = wfad.nFileSizeHigh;
  123. fileSize = liFileSize.QuadPart;
  124. }
  125. fSuccess = TRUE;
  126. Exit:
  127. if (pszActualSource != NULL)
  128. {
  129. CSxsPreserveLastError ple;
  130. ::LocalFree((HLOCAL) pszActualSource);
  131. ple.Restore();
  132. }
  133. return fSuccess;
  134. }
  135. BOOL
  136. SxspDoesFileExist(
  137. DWORD dwFlags,
  138. PCWSTR pszFileName,
  139. bool &rfExists
  140. )
  141. {
  142. BOOL fSuccess = FALSE;
  143. FN_TRACE_WIN32(fSuccess);
  144. PWSTR pszActualSource = NULL;
  145. rfExists = false;
  146. PARAMETER_CHECK(pszFileName != NULL);
  147. PARAMETER_CHECK((dwFlags & ~(SXSP_DOES_FILE_EXIST_FLAG_COMPRESSION_AWARE)) == 0);
  148. if (dwFlags & SXSP_DOES_FILE_EXIST_FLAG_COMPRESSION_AWARE)
  149. {
  150. DWORD dwTemp;
  151. DWORD dwSourceFileSize, dwTargetFileSize;
  152. UINT uiCompressionType;
  153. dwTemp = ::SetupGetFileCompressionInfoW(
  154. pszFileName,
  155. &pszActualSource,
  156. &dwSourceFileSize,
  157. &dwTargetFileSize,
  158. &uiCompressionType);
  159. if (pszActualSource != NULL)
  160. ::LocalFree((HLOCAL) pszActualSource);
  161. if (dwTemp == ERROR_FILE_NOT_FOUND)
  162. {
  163. // This case is OK. No error to return...
  164. }
  165. else if (dwTemp != ERROR_SUCCESS)
  166. ORIGINATE_WIN32_FAILURE_AND_EXIT(SetupGetFileCompressionInfoW, dwTemp);
  167. else
  168. {
  169. rfExists = true;
  170. }
  171. pszActualSource = NULL;
  172. }
  173. else
  174. {
  175. if (::GetFileAttributesW(pszFileName) == ((DWORD) -1))
  176. {
  177. const DWORD dwLastError = ::GetLastError();
  178. if (dwLastError != ERROR_FILE_NOT_FOUND)
  179. ORIGINATE_WIN32_FAILURE_AND_EXIT(GetFileAttributesW, dwLastError);
  180. }
  181. else
  182. rfExists = true;
  183. }
  184. fSuccess = TRUE;
  185. Exit:
  186. if (pszActualSource != NULL)
  187. {
  188. CSxsPreserveLastError ple;
  189. ::LocalFree((HLOCAL) pszActualSource);
  190. ple.Restore();
  191. }
  192. return fSuccess;
  193. }