windows-nt/Source/XPSP1/NT/base/win32/lz32/winlza/header.c
2020-09-26 16:20:57 +08:00

224 lines
5.9 KiB
C

/*
** header.c - Routines used to access compressed file header information.
**
** written by DavidDi
*/
// Headers
///////////
#ifndef LZA_DLL
#include <io.h>
#include <dos.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#endif
#include "lz_common.h"
#include "lz_buffers.h"
#include "lz_header.h"
/*
** int WriteHdr(PFH pFH, int doshDest);
**
** Write compressed file header to output file.
**
** Arguments: pFH - pointer to source header information structure
** doshDest - DOS file handle of open output file
**
** Returns: int - TRUE if successful. LZERROR_BADOUTHANDLE if
** unsuccessful.
**
** Globals: none
**
** header format:
** 8 bytes --> compressed file signature
** 1 byte --> algorithm label
** 1 byte --> extension char
** 4 bytes --> uncompressed file size (LSB to MSB)
**
** length = 14 bytes
*/
INT WriteHdr(PFH pFH, INT doshDest, PLZINFO pLZI)
{
INT i, j;
DWORD ucbWritten;
BYTE rgbyteHeaderBuf[HEADER_LEN]; // temporary storage for next header byte to write
// Sanity check
if (!pLZI) {
return(LZERROR_GLOBLOCK);
}
// Copy the compressed file signature.
for (i = 0; i < COMP_SIG_LEN; i++)
rgbyteHeaderBuf[i] = pFH->rgbyteMagic[i];
// Copy the algorithm label and file name extension character.
rgbyteHeaderBuf[i++] = pFH->byteAlgorithm;
rgbyteHeaderBuf[i++] = pFH->byteExtensionChar;
// Copy input file size (long ==> 4 bytes),
// LSB first to MSB last.
for (j = 0; j < 4; j++)
rgbyteHeaderBuf[i++] = (BYTE)((pFH->cbulUncompSize >> (8 * j)) &
(DWORD)BYTE_MASK);
// Write header to file.
if ((ucbWritten = FWRITE(doshDest, rgbyteHeaderBuf, HEADER_LEN)) != HEADER_LEN)
{
#ifdef LZA_DLL
if (ucbWritten == (DWORD)(-1))
#else
if (_error != 0U)
#endif
// Bad DOS file handle.
return(LZERROR_BADOUTHANDLE);
else
// Insufficient space on destination drive.
return(LZERROR_WRITE);
}
// Keep track of bytes written.
pLZI->cblOutSize += (LONG)ucbWritten;
// Header written ok.
return(TRUE);
}
/*
** int GetHdr(PFH pFH, int doshSource);
**
** Get compressed file header.
**
** Arguments: pFH - pointer to destination header information structure
** doshSource - DOS file handle of open input file
**
** Returns: int - TRUE if compressed file header read successfully. One
** the LZERROR_ codes if not.
**
** Globals: none
*/
INT GetHdr(PFH pFH, INT doshSource, LONG *pcblInSize)
{
DWORD ucbRead;
BYTE rgbyteHeaderBuf[HEADER_LEN];
INT i, j;
// Get input file length and move back to beginning of input file.
if ((*pcblInSize = FSEEK(doshSource, 0L, SEEK_END)) < 0L ||
FSEEK(doshSource, 0L, SEEK_SET) != 0L)
return(LZERROR_BADINHANDLE);
if ((ucbRead = FREAD(doshSource, rgbyteHeaderBuf, HEADER_LEN))
!= HEADER_LEN)
{
#ifdef LZA_DLL
if (ucbRead == (DWORD)(-1))
#else
if (_error != 0U)
#endif
// We were handed a bad input file handle.
return((INT)LZERROR_BADINHANDLE);
else
// Input file shorter than compressed header size.
return(LZERROR_READ);
}
// Put compressed file signature into rgbyteMagic[] of header info struct.
for (i = 0; i < COMP_SIG_LEN; i++)
pFH->rgbyteMagic[i] = rgbyteHeaderBuf[i];
// Get algorithm label and file name extension character.
pFH->byteAlgorithm = rgbyteHeaderBuf[i++];
pFH->byteExtensionChar = rgbyteHeaderBuf[i++];
// Extract uncompressed file size, LSB --> MSB (4 bytes in long).
pFH->cbulUncompSize = 0UL;
for (j = 0; j < 4; j++)
pFH->cbulUncompSize |= ((DWORD)(rgbyteHeaderBuf[i++]) << (8 * j));
// Stick compressed file size into header info struct.
pFH->cbulCompSize = (DWORD)*pcblInSize;
// File header read ok.
return(TRUE);
}
/*
** BOOL IsCompressed(PFH pFHIn);
**
** See if a file is in compressed form by comparing its file signature with
** the expected compressed file signature.
**
** Arguments: pFHIn - pointer to header info struct to check
**
** Returns: BOOL - TRUE if file signature matches expected compressed file
** signature. FALSE if not.
**
** Globals: none
*/
BOOL IsCompressed(PFH pFHIn)
{
INT i;
// storage for FHIn's compressed file signature (used to make it an sz)
CHAR rgchBuf[COMP_SIG_LEN + 1];
// Copy file info struct's compressed file signature into rgchBuf[] to
// make it an sz.
for (i = 0; i < COMP_SIG_LEN; i++)
rgchBuf[i] = pFHIn->rgbyteMagic[i];
rgchBuf[i] = '\0';
return((STRCMP(rgchBuf, COMP_SIG) == 0) ? TRUE : FALSE);
}
/*
** void MakeHeader(PFH pFHBlank, BYTE byteAlgorithm,
** BYTE byteExtensionChar);
**
** Arguments: pFHBlank - pointer to compressed file header struct
** that is to be filled in
** byteAlgorithm - algorithm label
** byteExtensionChar - uncompressed file name extension character
**
** Returns: void
**
** Globals: none
**
** Global cblInSize is used to fill in expanded file length field.
** Compressed file length field is set to 0 since it isn't written.
**
*/
VOID MakeHeader(PFH pFHBlank, BYTE byteAlgorithm,
BYTE byteExtensionChar, PLZINFO pLZI)
{
INT i;
// !!! Assumes pLZI parm is valid. No sanity check (should be done above in caller).
// Fill in compressed file signature.
for (i = 0; i < COMP_SIG_LEN; i++)
pFHBlank->rgbyteMagic[i] = (BYTE)(*(COMP_SIG + i));
// Fill in algorithm and extesion character.
pFHBlank->byteAlgorithm = byteAlgorithm;
pFHBlank->byteExtensionChar = byteExtensionChar;
// Fill in file sizes. (cbulCompSize not written to compressed file
// header, so just set it to 0UL.)
pFHBlank->cbulUncompSize = (DWORD)pLZI->cblInSize;
pFHBlank->cbulCompSize = 0UL;
}