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.
326 lines
7.4 KiB
326 lines
7.4 KiB
/*++
|
|
|
|
Copyright (C) 1997-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
COUT.CPP
|
|
|
|
Abstract:
|
|
|
|
Declares the COut class.
|
|
|
|
History:
|
|
|
|
a-davj 06-April-97 Created.
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#include <io.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <sys/stat.h>
|
|
#include <arrtempl.h>
|
|
|
|
#include "cout.h"
|
|
#include "trace.h"
|
|
#include "strings.h"
|
|
#include "mrciclass.h"
|
|
#include "bmof.h"
|
|
|
|
//***************************************************************************
|
|
//
|
|
// COut::COut
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Constructor. Allocates initial buffer.
|
|
//
|
|
//***************************************************************************
|
|
|
|
COut::COut(PDBG pDbg)
|
|
{
|
|
m_pDbg = pDbg;
|
|
m_dwSize = INIT_SIZE;
|
|
m_pMem = (BYTE *)malloc(m_dwSize);
|
|
m_dwCurr = 0;
|
|
m_bPadString = TRUE;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// COut::~COut
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Destructor. Frees the buffer.
|
|
//
|
|
//***************************************************************************
|
|
|
|
COut::~COut()
|
|
{
|
|
if(m_pMem)
|
|
free(m_pMem);
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// void COut::WriteToFile
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Creates a file and writes the buffer to it. Like other compilers, it
|
|
// overwrites any existing files.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// pFile File name to write to.
|
|
//
|
|
//***************************************************************************
|
|
|
|
BOOL COut::WriteToFile(
|
|
IN LPSTR pFile)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
BYTE * pCompressed = NULL;
|
|
DWORD one = 1;
|
|
DWORD dwSize;
|
|
int iRet;
|
|
DWORD dwCompressedSize;
|
|
DWORD dwSignature = BMOF_SIG;
|
|
CMRCICompression * pCompress = new CMRCICompression;
|
|
if(pCompress == NULL)
|
|
return FALSE;
|
|
CDeleteMe<CMRCICompression> dm(pCompress);
|
|
|
|
// Test if there are flavors
|
|
|
|
if(m_Flavors.Size() > 0)
|
|
{
|
|
// write out the flavor information
|
|
|
|
void * lOffSet;
|
|
void * lFlavor;
|
|
AppendBytes((BYTE *)"BMOFQUALFLAVOR11", 16);
|
|
long lNum = m_Flavors.Size();
|
|
AppendBytes( (BYTE *)&lNum, 4);
|
|
|
|
for(long lCnt = 0; lCnt < lNum; lCnt++)
|
|
{
|
|
lOffSet = m_Offsets.GetAt(lCnt);
|
|
lFlavor = m_Flavors.GetAt(lCnt);
|
|
AppendBytes( (BYTE *)&lOffSet, 4);
|
|
AppendBytes( (BYTE *)&lFlavor, 4);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
int fh = NULL;
|
|
if(pFile == NULL)
|
|
return FALSE;
|
|
|
|
fh = _open(pFile, _O_BINARY | O_RDWR | _O_TRUNC | _O_CREAT, _S_IREAD |_S_IWRITE);
|
|
if(fh == -1)
|
|
{
|
|
Trace(true, m_pDbg, FILE_CREATE_FAILED, pFile, errno);
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
// Create a compressed version of the blob
|
|
|
|
dwSize = (m_dwCurr > 0x7000) ? m_dwCurr : 0x7000;
|
|
|
|
pCompressed = new BYTE[dwSize];
|
|
if(pCompressed == NULL)
|
|
return FALSE;
|
|
|
|
dwCompressedSize = pCompress->Mrci1MaxCompress( m_pMem, m_dwCurr, pCompressed, dwSize);
|
|
|
|
if(dwCompressedSize == 0xffffffff || dwCompressedSize == 0)
|
|
{
|
|
Trace(true, m_pDbg, COMPRESSION_FAILED);
|
|
goto Cleanup;
|
|
}
|
|
|
|
// write the decomression signature, the decompressed size, and the compressed size
|
|
|
|
iRet = _write(fh, (BYTE *)&dwSignature, sizeof(DWORD));
|
|
if(iRet != sizeof(DWORD))
|
|
{
|
|
Trace(true, m_pDbg, FILE_WRITE_FAILED, pFile, errno);
|
|
goto Cleanup;
|
|
}
|
|
|
|
iRet = _write(fh, (BYTE *)&one, sizeof(DWORD));
|
|
iRet = _write(fh, (BYTE *)&dwCompressedSize, sizeof(DWORD));
|
|
iRet = _write(fh, (BYTE *)&m_dwCurr, sizeof(DWORD));
|
|
|
|
// write the compressed data and then free the buffer
|
|
|
|
iRet = _write(fh, pCompressed, dwCompressedSize);
|
|
|
|
if((DWORD)iRet != dwCompressedSize)
|
|
Trace(true, m_pDbg, FILE_WRITE_FAILED, pFile, errno);
|
|
else
|
|
bRet = TRUE;
|
|
|
|
Cleanup:
|
|
|
|
if(fh != NULL)
|
|
_close(fh);
|
|
if(pCompressed)
|
|
delete pCompressed;
|
|
return bRet;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DWORD COut::AppendBytes
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Adds bytes to the end of the buffer.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// pSrc Pointer to data source.
|
|
// dwSize Number of bytes to add.
|
|
//
|
|
// RETURN VALUE:
|
|
//
|
|
// Number of bytes added.
|
|
//
|
|
//***************************************************************************
|
|
|
|
DWORD COut::AppendBytes(
|
|
IN BYTE * pSrc,
|
|
IN DWORD dwSize)
|
|
{
|
|
char * pZero = "\0\0\0\0\0\0\0";
|
|
DWORD dwRet = WriteBytes(m_dwCurr, pSrc, dwSize);
|
|
m_dwCurr += dwRet;
|
|
DWORD dwLeftOver = dwSize & 3;
|
|
if(dwLeftOver && m_bPadString)
|
|
{
|
|
dwRet = WriteBytes(m_dwCurr, (BYTE *)pZero, dwLeftOver);
|
|
m_dwCurr += dwLeftOver;
|
|
}
|
|
return dwRet;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DWORD COut::WriteBSTR
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Adds a bstr to the buffer. Quite simple for now, by might be enhanced
|
|
// later on to compress.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// bstr bstr to add.
|
|
//
|
|
// RETURN VALUE:
|
|
//
|
|
// Number of bytes added.
|
|
//
|
|
//***************************************************************************
|
|
|
|
DWORD COut::WriteBSTR(
|
|
IN BSTR bstr)
|
|
{
|
|
return AppendBytes((BYTE *)bstr, 2*(wcslen(bstr) + 1));
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DWORD COut::WriteBytes
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// writes some bytes to the buffer, or possibly adds to the end.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// dwOffset Offset in buffer where bytes should go
|
|
// pSrc points to source data
|
|
// dwSize number of bytes to copy
|
|
//
|
|
// RETURN VALUE:
|
|
//
|
|
// Number of bytes copied
|
|
//
|
|
//***************************************************************************
|
|
|
|
DWORD COut::WriteBytes(
|
|
IN DWORD dwOffset,
|
|
IN BYTE * pSrc,
|
|
IN DWORD dwSize)
|
|
{
|
|
if(m_pMem == NULL)
|
|
return 0;
|
|
|
|
// check if reallocation is needed!
|
|
|
|
if(dwOffset + dwSize > m_dwSize)
|
|
{
|
|
DWORD dwAddSize = ADDITIONAL_SIZE;
|
|
if(dwSize > dwAddSize)
|
|
dwAddSize = dwSize;
|
|
BYTE * pNew = (BYTE *)realloc(m_pMem, m_dwSize + dwAddSize);
|
|
if(pNew == NULL)
|
|
{
|
|
free(m_pMem);
|
|
m_pMem = NULL;
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
m_pMem = pNew;
|
|
m_dwSize += dwAddSize;
|
|
}
|
|
}
|
|
|
|
memcpy(m_pMem+dwOffset, pSrc, dwSize);
|
|
return dwSize;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DWORD COut::AddFlavor
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Save the flavor value for the current offset.
|
|
//
|
|
// PARAMETERS:
|
|
//
|
|
// long flavor to be saved
|
|
//
|
|
// RETURN VALUE:
|
|
//
|
|
// TRUE if OK;
|
|
//
|
|
//***************************************************************************
|
|
|
|
BOOL COut::AddFlavor(IN long lFlavor)
|
|
{
|
|
#ifdef _WIN64
|
|
m_Offsets.Add((void *)IntToPtr(m_dwCurr));
|
|
m_Flavors.Add((void *)IntToPtr(lFlavor));
|
|
#else
|
|
m_Offsets.Add((void *)m_dwCurr);
|
|
m_Flavors.Add((void *)lFlavor);
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|