127 lines
2.8 KiB
C
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;
|
|
}
|