Leaked source code of windows server 2003
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.
 
 
 
 
 
 

370 lines
9.4 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: cba.cpp
//
// Contents: Implementation of CCryptBlobArray
//
// History: 23-Jul-97 kirtd Created
//
//----------------------------------------------------------------------------
#include <global.hxx>
//+---------------------------------------------------------------------------
//
// Member: CCryptBlobArray::CCryptBlobArray, public
//
// Synopsis: Initialize the internal CRYPT_BLOB_ARRAY
//
//----------------------------------------------------------------------------
CCryptBlobArray::CCryptBlobArray (
ULONG cMinBlobs,
ULONG cGrowBlobs,
BOOL& rfResult
)
{
rfResult = TRUE;
m_cGrowBlobs = cGrowBlobs;
m_cba.cBlob = 0;
m_cba.rgBlob = new CRYPT_DATA_BLOB [cMinBlobs];
if ( m_cba.rgBlob != NULL )
{
memset( m_cba.rgBlob, 0, sizeof(CRYPT_DATA_BLOB)*cMinBlobs );
m_cArray = cMinBlobs;
}
else
{
SetLastError( (DWORD) E_OUTOFMEMORY );
rfResult = FALSE;
}
}
//+---------------------------------------------------------------------------
//
// Member: CCryptBlobArray::CCryptBlobArray, public
//
// Synopsis: Initialize the internal CRYPT_BLOB_ARRAY with a native form
// blob array created via ::GetArrayInNativeForm
//
//----------------------------------------------------------------------------
CCryptBlobArray::CCryptBlobArray (
PCRYPT_BLOB_ARRAY pcba,
ULONG cGrowBlobs
)
{
m_cGrowBlobs = cGrowBlobs;
m_cba.cBlob = pcba->cBlob;
m_cba.rgBlob = pcba->rgBlob;
m_cArray = pcba->cBlob;
}
//+---------------------------------------------------------------------------
//
// Member: CCryptBlobArray::AllocBlob, public, static
//
// Synopsis: allocate a blob using the same allocator used for ::AddBlob
// copies. This means that the resulting blob can be added
// without copying.
//
//----------------------------------------------------------------------------
LPBYTE
CCryptBlobArray::AllocBlob (ULONG cb)
{
return( (LPBYTE)CryptMemAlloc( cb ) );
}
//+---------------------------------------------------------------------------
//
// Member: CCryptBlobArray::ReallocBlob, public, static
//
// Synopsis: see ::AllocBlob
//
//----------------------------------------------------------------------------
LPBYTE
CCryptBlobArray::ReallocBlob (LPBYTE pb, ULONG cb)
{
return( (LPBYTE)CryptMemRealloc( pb, cb ) );
}
//+---------------------------------------------------------------------------
//
// Member: CCryptBlobArray::FreeBlob, public
//
// Synopsis: free blob allocated using ::AllocBlob or ::ReallocBlob
//
//----------------------------------------------------------------------------
VOID
CCryptBlobArray::FreeBlob (LPBYTE pb)
{
CryptMemFree( pb );
}
//+---------------------------------------------------------------------------
//
// Member: CCryptBlobArray::AddBlob, public
//
// Synopsis: add a blob
//
//----------------------------------------------------------------------------
BOOL
CCryptBlobArray::AddBlob (
ULONG cb,
LPBYTE pb,
BOOL fCopyBlob
)
{
BOOL fResult = TRUE;
LPBYTE pbToUse;
//
// If we need to copy the blob, do so
//
if ( fCopyBlob == TRUE )
{
pbToUse = AllocBlob( cb );
if ( pbToUse != NULL )
{
memcpy( pbToUse, pb, cb );
}
else
{
SetLastError( (DWORD) E_OUTOFMEMORY );
return( FALSE );
}
}
else
{
pbToUse = pb;
}
//
// If we need to grow the array, do so
//
if ( m_cArray == m_cba.cBlob )
{
fResult = GrowArray();
}
//
// Add the blob to the array
//
if ( fResult == TRUE )
{
m_cba.rgBlob[m_cba.cBlob].cbData = cb;
m_cba.rgBlob[m_cba.cBlob].pbData = pbToUse;
m_cba.cBlob += 1;
}
else if ( fCopyBlob == TRUE )
{
FreeBlob( pbToUse );
}
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Member: CCryptBlobArray::GetBlob, public
//
// Synopsis: gets blob given an index
//
//----------------------------------------------------------------------------
PCRYPT_DATA_BLOB
CCryptBlobArray::GetBlob (ULONG index)
{
assert( m_cba.cBlob > index );
return( &m_cba.rgBlob[index] );
}
//+---------------------------------------------------------------------------
//
// Member: CCryptBlobArray::GetBlobCount, public
//
// Synopsis: get the count of blobs
//
//----------------------------------------------------------------------------
ULONG
CCryptBlobArray::GetBlobCount ()
{
return( m_cba.cBlob );
}
//+---------------------------------------------------------------------------
//
// Member: CCryptBlobArray::GetArrayInNativeForm, public
//
// Synopsis: get the array in native form
//
//----------------------------------------------------------------------------
VOID
CCryptBlobArray::GetArrayInNativeForm (PCRYPT_BLOB_ARRAY pcba)
{
pcba->cBlob = m_cba.cBlob;
pcba->rgBlob = m_cba.rgBlob;
}
//+---------------------------------------------------------------------------
//
// Member: CCryptBlobArray::GetArrayInSingleBufferEncodedForm, public
//
// Synopsis: gets the array in a single buffer encoded form
//
//----------------------------------------------------------------------------
BOOL
CCryptBlobArray::GetArrayInSingleBufferEncodedForm (
PCRYPT_BLOB_ARRAY* ppcba,
ULONG* pcb
)
{
ULONG cbStruct;
ULONG cbPointers;
ULONG cbData;
ULONG cb;
ULONG cbSize;
ULONG cCount;
PCRYPT_BLOB_ARRAY pcba = NULL;
//
// Calculate the buffer size we will need and allocate it
//
cbStruct = sizeof( CRYPT_BLOB_ARRAY );
cbPointers = m_cba.cBlob * sizeof( CRYPT_DATA_BLOB );
for ( cCount = 0, cbData = 0; cCount < m_cba.cBlob; cCount++ )
{
cbData += m_cba.rgBlob[cCount].cbData;
}
cbSize = cbStruct + cbPointers + cbData;
pcba = (PCRYPT_BLOB_ARRAY)CryptMemAlloc( cbSize );
if ( pcba == NULL )
{
SetLastError( (DWORD) E_OUTOFMEMORY );
return( FALSE );
}
//
// Fill in the data
//
pcba->cBlob = m_cba.cBlob;
pcba->rgBlob = (PCRYPT_DATA_BLOB)((LPBYTE)pcba+cbStruct);
__try
{
for ( cCount = 0, cb = 0; cCount < m_cba.cBlob; cCount++ )
{
pcba->rgBlob[cCount].cbData = m_cba.rgBlob[cCount].cbData;
pcba->rgBlob[cCount].pbData = (LPBYTE)pcba+cbStruct+cbPointers+cb;
memcpy(
pcba->rgBlob[cCount].pbData,
m_cba.rgBlob[cCount].pbData,
m_cba.rgBlob[cCount].cbData
);
cb += m_cba.rgBlob[cCount].cbData;
}
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
CryptMemFree( pcba );
SetLastError( GetExceptionCode() );
return( FALSE );
}
*ppcba = pcba;
if ( pcb != NULL )
{
*pcb = cbSize;
}
return( TRUE );
}
//+---------------------------------------------------------------------------
//
// Member: CCryptBlobArray::FreeArray, public
//
// Synopsis: frees the array and optionally frees the blobs
//
//----------------------------------------------------------------------------
VOID
CCryptBlobArray::FreeArray (BOOL fFreeBlobs)
{
if ( fFreeBlobs == TRUE )
{
ULONG cCount;
for ( cCount = 0; cCount < m_cba.cBlob; cCount++ )
{
FreeBlob( m_cba.rgBlob[cCount].pbData );
}
}
delete m_cba.rgBlob;
}
//+---------------------------------------------------------------------------
//
// Member: CCryptBlobArray::GrowArray, private
//
// Synopsis: grows the array
//
//----------------------------------------------------------------------------
BOOL
CCryptBlobArray::GrowArray ()
{
ULONG cNewArray;
PCRYPT_DATA_BLOB pcba;
//
// Check if we are allowed to grow
//
//
if ( m_cGrowBlobs == 0 )
{
SetLastError( (DWORD) E_INVALIDARG );
return( FALSE );
}
//
// Allocate and initialize the new array
//
cNewArray = m_cArray + m_cGrowBlobs;
pcba = new CRYPT_DATA_BLOB [cNewArray];
if ( pcba == NULL )
{
SetLastError( (DWORD) E_OUTOFMEMORY );
return( FALSE );
}
memset(pcba, 0, cNewArray*sizeof( CRYPT_DATA_BLOB ));
//
// Copy the old to the new
//
memcpy(pcba, m_cba.rgBlob, m_cba.cBlob*sizeof( CRYPT_DATA_BLOB ) );
//
// Free the old and use the new
//
delete m_cba.rgBlob;
m_cba.rgBlob = pcba;
m_cArray = cNewArray;
return( TRUE );
}