windows-nt/Source/XPSP1/NT/base/ntsetup/ntcab/lib/compress.c
2020-09-26 16:20:57 +08:00

127 lines
2.8 KiB
C

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
compress.c
Abstract:
This module contains the code to compress a file
into a cab file.
Author:
Wesley Witt (wesw) 29-Sept-1998
Revision History:
--*/
#include <ntcabp.h>
#pragma hdrstop
BOOL
NtCabCompressOneFile(
IN PCAB_INSTANCE_DATA CabInst,
IN PCWSTR FileName
)
{
NTSTATUS Status;
HANDLE hFile;
DWORD FileSize;
DWORD Bytes = 0;
DWORD BytesRead;
DWORD BytesCompressed;
DWORD Length = 0;
PCAB_DIR_ENTRY CabDir;
ULONG i;
BY_HANDLE_FILE_INFORMATION fi;
WCHAR ShortFileName[32];
hFile = CreateFile(
FileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
return GetLastError();
}
FileSize = GetFileSize( hFile, NULL );
BytesRead = sizeof(CAB_DIR_ENTRY) + (sizeof(ULONG)*64);
CabDir = (PCAB_DIR_ENTRY) malloc( BytesRead );
if (CabDir == NULL) {
return ERROR_NOT_ENOUGH_MEMORY;
}
ZeroMemory( CabDir, BytesRead );
GetFileInformationByHandle( hFile, &fi );
CabDir->FileAttributes = fi.dwFileAttributes;
CabDir->CreationTime = fi.ftCreationTime;
CabDir->LastAccessTime = fi.ftLastAccessTime;
CabDir->LastWriteTime = fi.ftLastWriteTime;
CabDir->FileSize = FileSize;
if (MapFileAndCheckSum( (PWSTR)FileName, &i, &CabDir->ChkSum ) != CHECKSUM_SUCCESS) {
CabDir->ChkSum = 0;
}
CabDir->Offset = SetFilePointer( CabInst->hCab, 0, NULL, FILE_CURRENT );
if (GetShortPathName( FileName, ShortFileName, sizeof(ShortFileName)/sizeof(WCHAR) ) == 0) {
return FALSE;
}
wcscpy( CabDir->FileName, ShortFileName );
i = 0;
while (Bytes < FileSize) {
BytesRead = min( CabInst->ReadBufSize, FileSize-Bytes );
Status = ReadFile(
hFile,
CabInst->ReadBuf,
BytesRead,
&BytesRead,
NULL
);
Bytes += BytesRead;
Status = RtlCompressBuffer(
COMPRESSION_FLAGS,
CabInst->ReadBuf,
BytesRead,
CabInst->CompressBuf,
CabInst->CompressBufSize,
4096,
&BytesCompressed,
CabInst->WorkSpace
);
Status = WriteFile(
CabInst->hCab,
CabInst->CompressBuf,
BytesCompressed,
&BytesRead,
NULL
);
Length += BytesRead;
CabDir->Segment[i++] = BytesRead;
CabDir->CompressedFileSize += BytesRead;
}
CabDir->Segments = i;
InsertTailList( &CabInst->CabDir, &CabDir->Next );
CloseHandle( hFile );
CabInst->CabNum += 1;
return 0;
}