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.

322 lines
6.9 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. cabinet.cpp
  5. Abstract:
  6. cabinet management Function calls for msm generation
  7. Author:
  8. Xiaoyu Wu(xiaoyuw) 01-Aug-2001
  9. --*/
  10. #include "msmgen.h"
  11. #include "util.h"
  12. extern BOOL __stdcall SxspDeleteDirectory(const CBaseStringBuffer &rdir);
  13. #include <fci.h>
  14. #include <fdi.h>
  15. #include "msmfci.h"
  16. #include "msmfdi.h"
  17. ERF erf;
  18. //
  19. // FCI
  20. //
  21. HRESULT InitializeCabinetForWrite()
  22. {
  23. HFCI hfci;
  24. CCAB cab_parameters;
  25. client_state cs;
  26. HRESULT hr = S_OK;
  27. // Initialise our internal state
  28. cs.total_compressed_size = 0;
  29. cs.total_uncompressed_size = 0;
  30. set_cab_parameters(&cab_parameters);
  31. hfci = FCICreate(
  32. &erf,
  33. file_placed,
  34. fci_mem_alloc,
  35. fci_mem_free,
  36. fci_open,
  37. fci_read,
  38. fci_write,
  39. fci_close,
  40. fci_seek,
  41. fci_delete,
  42. get_temp_file,
  43. &cab_parameters,
  44. &cs
  45. );
  46. if (hfci == NULL)
  47. {
  48. printf("CAB: FCICreate() failed: code %d [%s]\n",
  49. erf.erfOper, return_fci_error_string(erf.erfOper));
  50. SETFAIL_AND_EXIT;
  51. }else
  52. {
  53. g_MsmInfo.m_hfci = hfci;
  54. hfci= NULL;
  55. }
  56. Exit:
  57. return hr;
  58. }
  59. HRESULT AddFileToCabinetW(PCWSTR full_filename, SIZE_T CchFullFileName, PCWSTR relative_filename, SIZE_T CchRelativePath)
  60. {
  61. HRESULT hr = S_OK;
  62. CHAR pszpath[MAX_PATH];
  63. CHAR pszfilename[MAX_PATH];
  64. WideCharToMultiByte(
  65. CP_ACP, 0, full_filename, (int)CchFullFileName,
  66. pszpath, MAX_PATH, NULL, NULL);
  67. pszpath[CchFullFileName] = '\0';
  68. WideCharToMultiByte(
  69. CP_ACP, 0, relative_filename, (int)CchRelativePath,
  70. pszfilename, MAX_PATH, NULL, NULL);
  71. pszfilename[CchRelativePath] = '\0';
  72. if (FALSE == FCIAddFile(
  73. g_MsmInfo.m_hfci,
  74. pszpath, /* filename to add : fully qualified filename */
  75. pszfilename, /* file name in cabinet file : relative filepath */
  76. FALSE, /* file is not executable */
  77. get_next_cabinet,
  78. progress,
  79. get_open_info,
  80. COMPRESSION_TYPE))
  81. {
  82. fprintf(stderr, "adding file %s to the cabinet failed\n", pszpath);
  83. SETFAIL_AND_EXIT;
  84. }
  85. Exit:
  86. return hr;
  87. }
  88. HRESULT AddFileToCabinetA(PCSTR full_filename, SIZE_T CchFullFileName, PCSTR relative_filename, SIZE_T CchRelativePath)
  89. {
  90. HRESULT hr = S_OK;
  91. WCHAR szFullFilename[MAX_PATH];
  92. WCHAR szRelativeFilename[MAX_PATH];
  93. swprintf(szFullFilename, L"%S", full_filename);
  94. swprintf(szRelativeFilename, L"%S", relative_filename);
  95. IFFAILED_EXIT(AddFileToCabinetW(szFullFilename, CchFullFileName, szRelativeFilename, CchRelativePath));
  96. Exit:
  97. return hr;
  98. }
  99. HRESULT CloseCabinet()
  100. {
  101. HRESULT hr = S_OK;
  102. CurrentAssemblyRealign;
  103. if (FALSE == FCIFlushCabinet(
  104. g_MsmInfo.m_hfci,
  105. FALSE,
  106. get_next_cabinet,
  107. progress))
  108. {
  109. fprintf(stderr, "Flush Cabinet failed\n");
  110. hr = HRESULT_FROM_WIN32(::GetLastError());
  111. goto Exit;
  112. }
  113. if (FCIDestroy(g_MsmInfo.m_hfci) != TRUE)
  114. {
  115. SETFAIL_AND_EXIT;
  116. }
  117. else
  118. g_MsmInfo.m_hfci = NULL;
  119. Exit:
  120. return hr;
  121. }
  122. //
  123. // FDI
  124. //
  125. HRESULT MoveFilesInCabinetA(char * sourceCabinet)
  126. {
  127. HRESULT hr = S_OK;
  128. HFDI hfdi = NULL;
  129. ERF erf;
  130. FDICABINETINFO fdici;
  131. INT_PTR hf = -1;
  132. DWORD num;
  133. extern char dest_dir[MAX_PATH];
  134. hfdi = FDICreate(
  135. fdi_mem_alloc,
  136. fdi_mem_free,
  137. fdi_file_open,
  138. fdi_file_read,
  139. fdi_file_write,
  140. fdi_file_close,
  141. fdi_file_seek,
  142. cpu80386,
  143. &erf
  144. );
  145. if (hfdi == NULL)
  146. {
  147. printf("FDICreate() failed: code %d [%s]\n",
  148. erf.erfOper, return_fdi_error_string(erf.erfOper)
  149. );
  150. SETFAIL_AND_EXIT;
  151. }
  152. hf = fdi_file_open(
  153. sourceCabinet,
  154. _O_BINARY | _O_RDONLY | _O_SEQUENTIAL,
  155. 0
  156. );
  157. if (hf == -1)
  158. {
  159. printf("Unable to open '%s' for input\n", sourceCabinet);
  160. SETFAIL_AND_EXIT;
  161. }
  162. if (FALSE == FDIIsCabinet(
  163. hfdi,
  164. hf,
  165. &fdici))
  166. {
  167. /*
  168. * It is not a cabinet!, BUT it must be since it is named as MergeModule.cab in a msm
  169. */
  170. printf(
  171. "FDIIsCabinet() failed: '%s' is not a cabinet\n",
  172. sourceCabinet
  173. );
  174. SETFAIL_AND_EXIT;
  175. }
  176. else
  177. {
  178. _close((int)hf);
  179. #ifdef MSMGEN_TEST
  180. printf(
  181. "Information on cabinet file '%s'\n"
  182. " Total length of cabinet file : %d\n"
  183. " Number of folders in cabinet : %d\n"
  184. " Number of files in cabinet : %d\n"
  185. " Cabinet set ID : %d\n"
  186. " Cabinet number in set : %d\n"
  187. " RESERVE area in cabinet? : %s\n"
  188. " Chained to prev cabinet? : %s\n"
  189. " Chained to next cabinet? : %s\n"
  190. "\n",
  191. sourceCabinet,
  192. fdici.cbCabinet,
  193. fdici.cFolders,
  194. fdici.cFiles,
  195. fdici.setID,
  196. fdici.iCabinet,
  197. fdici.fReserve == TRUE ? "yes" : "no",
  198. fdici.hasprev == TRUE ? "yes" : "no",
  199. fdici.hasnext == TRUE ? "yes" : "no"
  200. );
  201. #endif
  202. if ((fdici.fReserve == TRUE)|| (fdici.hasprev == TRUE) || (fdici.hasnext == TRUE))
  203. {
  204. printf("ERROR file format : MSI 1.5 support one and only one cabinet in MergeModule.cab!\n");
  205. SETFAIL_AND_EXIT;
  206. }
  207. }
  208. //
  209. // create a temporary directory for use
  210. //
  211. num = ExpandEnvironmentStringsA(MSM_TEMP_CABIN_DIRECTORY_A, dest_dir, NUMBER_OF(dest_dir));
  212. if ( (num == 0) || (num > NUMBER_OF(dest_dir)))
  213. SETFAIL_AND_EXIT;
  214. DWORD dwAttribs = GetFileAttributesA(dest_dir);
  215. if (dwAttribs != (DWORD)(-1))
  216. {
  217. if ((dwAttribs & FILE_ATTRIBUTE_DIRECTORY) == 0 )
  218. SETFAIL_AND_EXIT;
  219. CStringBuffer sb;
  220. WCHAR wdir[MAX_PATH];
  221. num = ExpandEnvironmentStringsW(MSM_TEMP_CABIN_DIRECTORY_W, wdir, NUMBER_OF(wdir));
  222. if ( (num == 0) || (num > NUMBER_OF(wdir)))
  223. SETFAIL_AND_EXIT;
  224. IFFALSE_EXIT(sb.Win32Assign(wdir, wcslen(wdir)));
  225. IFFALSE_EXIT(SxspDeleteDirectory(sb));
  226. }
  227. IFFALSE_EXIT(CreateDirectoryA(dest_dir, NULL));
  228. char * p = NULL;
  229. char sourceDir[MAX_PATH];
  230. p = strrchr(sourceCabinet, '\\');
  231. ASSERT_NTC(p != NULL);
  232. p ++; // skip "\"
  233. strncpy(sourceDir, sourceCabinet, p - sourceCabinet);
  234. sourceDir[p - sourceCabinet] = '\0';
  235. if (TRUE != FDICopy(
  236. hfdi,
  237. p,
  238. sourceDir,
  239. 0,
  240. fdi_notification_function,
  241. NULL,
  242. NULL))
  243. {
  244. printf(
  245. "FDICopy() failed: code %d [%s]\n",
  246. erf.erfOper, return_fdi_error_string(erf.erfOper)
  247. );
  248. (void) FDIDestroy(hfdi);
  249. return FALSE;
  250. }
  251. if (FDIDestroy(hfdi) != TRUE)
  252. {
  253. printf(
  254. "FDIDestroy() failed: code %d [%s]\n",
  255. erf.erfOper, return_fdi_error_string(erf.erfOper)
  256. );
  257. return FALSE;
  258. }
  259. hfdi = NULL;
  260. Exit:
  261. if (hfdi != NULL)
  262. (void) FDIDestroy(hfdi);
  263. if ( hf != -1)
  264. _close((int)hf);
  265. return hr;
  266. }