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.

572 lines
12 KiB

  1. /*++
  2. Module Name:
  3. diamond.c
  4. Abstract:
  5. Diamond compression interface.
  6. This module contains functions to compress a file using
  7. the mszip compression library.
  8. Author:
  9. Ted Miller
  10. Environment:
  11. Windows
  12. --*/
  13. #include <windows.h>
  14. #include <stdio.h>
  15. #include "lz_common.h"
  16. #include "lz_buffers.h"
  17. #include "lz_header.h"
  18. #include <io.h>
  19. #include <fcntl.h>
  20. #include <errno.h>
  21. #include "main.h"
  22. #include <diamondc.h>
  23. #include "mydiam.h"
  24. typedef struct _DIAMOND_INFO {
  25. DWORD SourceFileSize;
  26. DWORD CompressedSize;
  27. FILETIME SourceFileCreationTime;
  28. FILETIME SourceFileModifiedTime;
  29. FILETIME SourceFileAccessedTime;
  30. } DIAMOND_INFO, *PDIAMOND_INFO;
  31. //
  32. // Callback functions to perform memory allocation, io, etc.
  33. // We pass addresses of these functions to diamond.
  34. //
  35. int
  36. DIAMONDAPI
  37. fciFilePlacedCB(
  38. OUT PCCAB Cabinet,
  39. IN PSTR FileName,
  40. IN LONG FileSize,
  41. IN BOOL Continuation,
  42. IN PVOID Context
  43. )
  44. /*++
  45. Routine Description:
  46. Callback used by diamond to indicate that a file has been
  47. comitted to a cabinet.
  48. No action is taken and success is returned.
  49. Arguments:
  50. Cabinet - cabinet structure to fill in.
  51. FileName - name of file in cabinet
  52. FileSize - size of file in cabinet
  53. Continuation - TRUE if this is a partial file, continuation
  54. of compression begun in a different cabinet.
  55. Context - supplies context information.
  56. Return Value:
  57. 0 (success).
  58. --*/
  59. {
  60. UNREFERENCED_PARAMETER(Cabinet);
  61. UNREFERENCED_PARAMETER(FileName);
  62. UNREFERENCED_PARAMETER(FileSize);
  63. UNREFERENCED_PARAMETER(Continuation);
  64. UNREFERENCED_PARAMETER(Context);
  65. return(0);
  66. }
  67. PVOID
  68. DIAMONDAPI
  69. fciAllocCB(
  70. IN ULONG NumberOfBytes
  71. )
  72. /*++
  73. Routine Description:
  74. Callback used by diamond to allocate memory.
  75. Arguments:
  76. NumberOfBytes - supplies desired size of block.
  77. Return Value:
  78. Returns pointer to a block of memory or NULL
  79. if memory cannot be allocated.
  80. --*/
  81. {
  82. return((PVOID)LocalAlloc(LMEM_FIXED,NumberOfBytes));
  83. }
  84. VOID
  85. DIAMONDAPI
  86. fciFreeCB(
  87. IN PVOID Block
  88. )
  89. /*++
  90. Routine Description:
  91. Callback used by diamond to free a memory block.
  92. The block must have been allocated with fciAlloc().
  93. Arguments:
  94. Block - supplies pointer to block of memory to be freed.
  95. Return Value:
  96. None.
  97. --*/
  98. {
  99. LocalFree((HLOCAL)Block);
  100. }
  101. FNFCIGETTEMPFILE(fciTempFileCB)
  102. {
  103. CHAR TempPath[MAX_PATH];
  104. DWORD cchTemp;
  105. cchTemp = GetTempPath(sizeof(TempPath), TempPath);
  106. if ((cchTemp == 0) || (cchTemp >= sizeof(TempPath))) {
  107. TempPath[0] = '.';
  108. TempPath[1] = '\0';
  109. }
  110. if(GetTempFileNameA(TempPath,"dc",0,pszTempName)) {
  111. DeleteFileA(pszTempName);
  112. }
  113. return(TRUE);
  114. }
  115. BOOL
  116. DIAMONDAPI
  117. fciNextCabinetCB(
  118. OUT PCCAB Cabinet,
  119. IN DWORD CabinetSizeEstimate,
  120. IN PVOID Context
  121. )
  122. /*++
  123. Routine Description:
  124. Callback used by diamond to request a new cabinet file.
  125. This functionality is not used in our implementation as
  126. we deal only with single-file cabinets.
  127. Arguments:
  128. Cabinet - cabinet structure to be filled in.
  129. CabinetSizeEstimate - estimated size of cabinet.
  130. Context - supplies context information.
  131. Return Value:
  132. FALSE (failure).
  133. --*/
  134. {
  135. UNREFERENCED_PARAMETER(Cabinet);
  136. UNREFERENCED_PARAMETER(CabinetSizeEstimate);
  137. UNREFERENCED_PARAMETER(Context);
  138. return(FALSE);
  139. }
  140. BOOL
  141. DIAMONDAPI
  142. fciStatusCB(
  143. IN UINT StatusType,
  144. IN DWORD Count1,
  145. IN DWORD Count2,
  146. IN PVOID Context
  147. )
  148. /*++
  149. Routine Description:
  150. Callback used by diamond to give status on file compression
  151. and cabinet operations, etc.
  152. Arguments:
  153. Status Type - supplies status type.
  154. 0 = statusFile - compressing block into a folder.
  155. Count1 = compressed size
  156. Count2 = uncompressed size
  157. 1 = statusFolder - performing AddFilder.
  158. Count1 = bytes done
  159. Count2 = total bytes
  160. Context - supplies context info.
  161. Return Value:
  162. TRUE (success).
  163. --*/
  164. {
  165. PDIAMOND_INFO context;
  166. UNREFERENCED_PARAMETER(Count2);
  167. context = (PDIAMOND_INFO)Context;
  168. if(StatusType == statusFile) {
  169. //
  170. // Track compressed size.
  171. //
  172. context->CompressedSize += Count1;
  173. }
  174. return(TRUE);
  175. }
  176. FNFCIGETOPENINFO(fciOpenInfoCB)
  177. {
  178. int h;
  179. WIN32_FIND_DATAA FindData;
  180. HANDLE FindHandle;
  181. PDIAMOND_INFO context;
  182. FILETIME ftLocal;
  183. context = pv;
  184. FindHandle = FindFirstFileA(pszName,&FindData);
  185. if(FindHandle == INVALID_HANDLE_VALUE) {
  186. return(-1);
  187. }
  188. FindClose(FindHandle);
  189. context->SourceFileSize = FindData.nFileSizeLow;
  190. context->SourceFileCreationTime = FindData.ftCreationTime;
  191. context->SourceFileModifiedTime = FindData.ftLastWriteTime;
  192. context->SourceFileAccessedTime = FindData.ftLastAccessTime;
  193. FileTimeToLocalFileTime(&FindData.ftLastWriteTime, &ftLocal);
  194. FileTimeToDosDateTime(&ftLocal, pdate, ptime);
  195. *pattribs = (WORD)(FindData.dwFileAttributes &
  196. ( FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN |
  197. FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE ));
  198. h = _open(pszName,_O_RDONLY | _O_BINARY);
  199. if(h == -1) {
  200. return(-1);
  201. }
  202. return(h);
  203. }
  204. FNFCIOPEN(fciOpen)
  205. {
  206. int result;
  207. result = _open(pszFile, oflag, pmode);
  208. if (result == -1) {
  209. *err = errno;
  210. }
  211. return(result);
  212. }
  213. FNFCIREAD(fciRead)
  214. {
  215. UINT result;
  216. result = (UINT) _read((HFILE)hf, memory, cb);
  217. if (result != cb) {
  218. *err = errno;
  219. }
  220. return(result);
  221. }
  222. FNFCIWRITE(fciWrite)
  223. {
  224. UINT result;
  225. result = (UINT) _write((HFILE)hf, memory, cb);
  226. if (result != cb) {
  227. *err = errno;
  228. }
  229. return(result);
  230. }
  231. FNFCICLOSE(fciClose)
  232. {
  233. int result;
  234. result = _close((HFILE)hf);
  235. if (result == -1) {
  236. *err = errno;
  237. }
  238. return(result);
  239. }
  240. FNFCISEEK(fciSeek)
  241. {
  242. long result;
  243. result = _lseek((HFILE)hf, dist, seektype);
  244. if (result == -1) {
  245. *err = errno;
  246. }
  247. return(result);
  248. }
  249. FNFCIDELETE(fciDelete)
  250. {
  251. int result;
  252. result = _unlink(pszFile);
  253. if (result == -1) {
  254. *err = errno;
  255. }
  256. return(result);
  257. }
  258. INT
  259. DiamondCompressFile(
  260. IN NOTIFYPROC CompressNotify,
  261. IN PSTR SourceFile,
  262. IN PSTR TargetFile,
  263. IN BOOL Rename,
  264. OUT PLZINFO pLZI
  265. )
  266. {
  267. BOOL b;
  268. PSTR SourceFilenamePart,p;
  269. HFCI FciContext;
  270. ERF FciError;
  271. CCAB ccab;
  272. CHAR targetFile[MAX_PATH];
  273. DIAMOND_INFO Context;
  274. INT Status;
  275. __try {
  276. //
  277. // Isolate the filename part of the source file.
  278. //
  279. if(SourceFilenamePart = strrchr(SourceFile,'\\')) {
  280. SourceFilenamePart++;
  281. } else {
  282. SourceFilenamePart = SourceFile;
  283. }
  284. //
  285. // Form the actual name of the target file.
  286. //
  287. lstrcpy(targetFile,TargetFile);
  288. if(Rename) {
  289. MakeCompressedName(targetFile);
  290. }
  291. //
  292. // Fill in the cabinet structure.
  293. //
  294. ZeroMemory(&ccab,sizeof(ccab));
  295. lstrcpyA(ccab.szCabPath,targetFile);
  296. if(p=strrchr(ccab.szCabPath,'\\')) {
  297. lstrcpyA(ccab.szCab,++p);
  298. *p = 0;
  299. } else {
  300. lstrcpyA(ccab.szCab,targetFile);
  301. ccab.szCabPath[0] = 0;
  302. }
  303. //
  304. // Call the notification function to see whether we are really
  305. // supposed to compress this file.
  306. //
  307. if(!CompressNotify(SourceFile,targetFile,NOTIFY_START_COMPRESS)) {
  308. Status = BLANK_ERROR;
  309. __leave;
  310. }
  311. ZeroMemory(&Context,sizeof(Context));
  312. //
  313. // Compress the file.
  314. //
  315. FciContext = FCICreate(
  316. &FciError,
  317. fciFilePlacedCB,
  318. fciAllocCB,
  319. fciFreeCB,
  320. fciOpen,
  321. fciRead,
  322. fciWrite,
  323. fciClose,
  324. fciSeek,
  325. fciDelete,
  326. fciTempFileCB,
  327. &ccab,
  328. &Context
  329. );
  330. if(FciContext) {
  331. b = FCIAddFile(
  332. FciContext,
  333. SourceFile, // file to add to cabinet.
  334. SourceFilenamePart, // filename part, name to store in cabinet.
  335. FALSE,
  336. fciNextCabinetCB, // routine for next cabinet (always fails)
  337. fciStatusCB,
  338. fciOpenInfoCB,
  339. DiamondCompressionType
  340. );
  341. if(b) {
  342. b = FCIFlushCabinet(
  343. FciContext,
  344. FALSE,
  345. fciNextCabinetCB,
  346. fciStatusCB
  347. );
  348. if(b) {
  349. HANDLE FindHandle;
  350. WIN32_FIND_DATA FindData;
  351. //
  352. // Context.CompressedSize does not include headers
  353. // and any other file overhead.
  354. //
  355. FindHandle = FindFirstFile(targetFile,&FindData);
  356. if(FindHandle == INVALID_HANDLE_VALUE) {
  357. pLZI->cblOutSize = (LONG)Context.CompressedSize;
  358. } else {
  359. pLZI->cblOutSize = (LONG)FindData.nFileSizeLow;
  360. FindClose(FindHandle);
  361. }
  362. pLZI->cblInSize = (LONG)Context.SourceFileSize;
  363. FindHandle = CreateFile(targetFile,
  364. GENERIC_READ | GENERIC_WRITE,
  365. 0,
  366. NULL,
  367. OPEN_EXISTING,
  368. 0,
  369. NULL);
  370. if (FindHandle != INVALID_HANDLE_VALUE)
  371. {
  372. SetFileTime(FindHandle,
  373. &Context.SourceFileCreationTime,
  374. &Context.SourceFileAccessedTime,
  375. &Context.SourceFileModifiedTime);
  376. CloseHandle(FindHandle);
  377. }
  378. }
  379. }
  380. if(b) {
  381. Status = TRUE;
  382. } else {
  383. switch(FciError.erfOper) {
  384. case FCIERR_OPEN_SRC:
  385. Status = LZERROR_BADINHANDLE;
  386. break;
  387. case FCIERR_READ_SRC:
  388. Status = LZERROR_READ;
  389. break;
  390. case FCIERR_CAB_FILE:
  391. Status = LZERROR_WRITE;
  392. break;
  393. case FCIERR_ALLOC_FAIL:
  394. Status = LZERROR_GLOBALLOC;
  395. break;
  396. case FCIERR_TEMP_FILE:
  397. case FCIERR_BAD_COMPR_TYPE:
  398. case FCIERR_USER_ABORT:
  399. case FCIERR_MCI_FAIL:
  400. default:
  401. Status = FALSE;
  402. }
  403. }
  404. FCIDestroy(FciContext);
  405. } else {
  406. Status = LZERROR_GLOBALLOC;
  407. }
  408. } __except(EXCEPTION_EXECUTE_HANDLER) {
  409. Status = GetLastError();
  410. }
  411. return(Status);
  412. }