/*++ 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 #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; }