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.

126 lines
2.8 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. compress.c
  5. Abstract:
  6. This module contains the code to compress a file
  7. into a cab file.
  8. Author:
  9. Wesley Witt (wesw) 29-Sept-1998
  10. Revision History:
  11. --*/
  12. #include <ntcabp.h>
  13. #pragma hdrstop
  14. BOOL
  15. NtCabCompressOneFile(
  16. IN PCAB_INSTANCE_DATA CabInst,
  17. IN PCWSTR FileName
  18. )
  19. {
  20. NTSTATUS Status;
  21. HANDLE hFile;
  22. DWORD FileSize;
  23. DWORD Bytes = 0;
  24. DWORD BytesRead;
  25. DWORD BytesCompressed;
  26. DWORD Length = 0;
  27. PCAB_DIR_ENTRY CabDir;
  28. ULONG i;
  29. BY_HANDLE_FILE_INFORMATION fi;
  30. WCHAR ShortFileName[32];
  31. hFile = CreateFile(
  32. FileName,
  33. GENERIC_READ,
  34. FILE_SHARE_READ,
  35. NULL,
  36. OPEN_EXISTING,
  37. FILE_ATTRIBUTE_NORMAL,
  38. NULL
  39. );
  40. if (hFile == INVALID_HANDLE_VALUE) {
  41. return GetLastError();
  42. }
  43. FileSize = GetFileSize( hFile, NULL );
  44. BytesRead = sizeof(CAB_DIR_ENTRY) + (sizeof(ULONG)*64);
  45. CabDir = (PCAB_DIR_ENTRY) malloc( BytesRead );
  46. if (CabDir == NULL) {
  47. return ERROR_NOT_ENOUGH_MEMORY;
  48. }
  49. ZeroMemory( CabDir, BytesRead );
  50. GetFileInformationByHandle( hFile, &fi );
  51. CabDir->FileAttributes = fi.dwFileAttributes;
  52. CabDir->CreationTime = fi.ftCreationTime;
  53. CabDir->LastAccessTime = fi.ftLastAccessTime;
  54. CabDir->LastWriteTime = fi.ftLastWriteTime;
  55. CabDir->FileSize = FileSize;
  56. if (MapFileAndCheckSum( (PWSTR)FileName, &i, &CabDir->ChkSum ) != CHECKSUM_SUCCESS) {
  57. CabDir->ChkSum = 0;
  58. }
  59. CabDir->Offset = SetFilePointer( CabInst->hCab, 0, NULL, FILE_CURRENT );
  60. if (GetShortPathName( FileName, ShortFileName, sizeof(ShortFileName)/sizeof(WCHAR) ) == 0) {
  61. return FALSE;
  62. }
  63. wcscpy( CabDir->FileName, ShortFileName );
  64. i = 0;
  65. while (Bytes < FileSize) {
  66. BytesRead = min( CabInst->ReadBufSize, FileSize-Bytes );
  67. Status = ReadFile(
  68. hFile,
  69. CabInst->ReadBuf,
  70. BytesRead,
  71. &BytesRead,
  72. NULL
  73. );
  74. Bytes += BytesRead;
  75. Status = RtlCompressBuffer(
  76. COMPRESSION_FLAGS,
  77. CabInst->ReadBuf,
  78. BytesRead,
  79. CabInst->CompressBuf,
  80. CabInst->CompressBufSize,
  81. 4096,
  82. &BytesCompressed,
  83. CabInst->WorkSpace
  84. );
  85. Status = WriteFile(
  86. CabInst->hCab,
  87. CabInst->CompressBuf,
  88. BytesCompressed,
  89. &BytesRead,
  90. NULL
  91. );
  92. Length += BytesRead;
  93. CabDir->Segment[i++] = BytesRead;
  94. CabDir->CompressedFileSize += BytesRead;
  95. }
  96. CabDir->Segments = i;
  97. InsertTailList( &CabInst->CabDir, &CabDir->Next );
  98. CloseHandle( hFile );
  99. CabInst->CabNum += 1;
  100. return 0;
  101. }