Renamed version4 to flaim and version5 to xflaim

git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@7 0109f412-320b-0410-ab79-c3e0c5ffbbe6
This commit is contained in:
dsandersoremutah
2006-01-27 21:06:39 +00:00
parent 4072ed64c8
commit c55dab446f
612 changed files with 0 additions and 0 deletions

744
flaim/src/flcreate.cpp Normal file
View File

@@ -0,0 +1,744 @@
//-------------------------------------------------------------------------
// Desc: Create database.
// Tabs: 3
//
// Copyright (c) 1990-2006 Novell, Inc. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, contact Novell, Inc.
//
// To contact Novell about this file by physical or electronic mail,
// you may find current contact information at www.novell.com
//
// $Id: flcreate.cpp 12329 2006-01-20 17:49:30 -0700 (Fri, 20 Jan 2006) ahodgkinson $
//-------------------------------------------------------------------------
#include "flaimsys.h"
FSTATIC RCODE flmInitNewFile(
FDB * pDb,
const char * pszRflDir,
const char * pszDictFileName,
const char * pszDictBuf,
CREATE_OPTS * pCreateOpts,
FLMUINT uiTransID);
FSTATIC RCODE flmInitFileHdrs(
FDB * pDb,
CREATE_OPTS * pCreateOpts,
FLMUINT uiBlkSize,
FLMUINT uiTransID,
FLMBYTE * pInitBuf,
FLMUINT uiBufSize);
/*API~***********************************************************************
Desc : Creates a new FLAIM database.
*END************************************************************************/
RCODE FlmDbCreate(
const char * pszDbFileName,
const char * pszDataDir,
const char * pszRflDir,
const char * pszDictFileName,
const char * pszDictBuf,
CREATE_OPTS * pCreateOpts,
HFDB * phDbRV)
{
RCODE rc = FERR_OK;
CS_CONTEXT * pCSContext;
*phDbRV = HFDB_NULL;
if( !pszDbFileName || !pszDbFileName[ 0])
{
rc = RC_SET( FERR_IO_INVALID_PATH);
goto Exit;
}
if (RC_BAD( rc = flmGetCSConnection(
pszDbFileName, &pCSContext)))
{
goto Exit;
}
if (pCSContext)
{
if( RC_BAD( rc = flmOpenOrCreateDbClientServer( pszDbFileName,
pszDataDir, pszRflDir, 0, pszDictFileName,
pszDictBuf, pCreateOpts, FALSE, pCSContext, (FDB_p *)phDbRV)))
{
(void)flmCloseCSConnection( &pCSContext);
}
goto Exit;
}
if( RC_BAD( rc = flmCreateNewFile( pszDbFileName, pszDataDir, pszRflDir,
pszDictFileName, pszDictBuf, pCreateOpts,
0, (FDB_p *)phDbRV)))
{
goto Exit;
}
Exit:
return( rc);
}
/****************************************************************************
Desc: This routine creates a FLAIM file.
****************************************************************************/
RCODE flmCreateNewFile(
const char * pszFilePath,
const char * pszDataDir,
const char * pszRflDir,
const char * pszDictFileName,
const char * pszDictBuf,
CREATE_OPTS * pCreateOpts,
FLMUINT uiTransID,
FDB_p * ppDb,
REBUILD_STATE * pRebuildState)
{
RCODE rc = FERR_OK;
FDB * pDb;
FFILE * pFile;
FLMBOOL bFileCreated = FALSE;
FLMBOOL bNewFile = FALSE;
FLMBOOL bAllocatedFdb = FALSE;
FLMBOOL bMutexLocked = FALSE;
*ppDb = NULL;
#ifndef FLM_USE_NICI
F_UNREFERENCED_PARM( pRebuildState);
#endif
// Allocate and initialize an FDB structure.
if (RC_BAD( rc = flmAllocFdb( ppDb)))
{
goto Exit;
}
pDb = *ppDb;
bAllocatedFdb = TRUE;
f_mutexLock( gv_FlmSysData.hShareMutex);
bMutexLocked = TRUE;
// Free any unused structures that have been unused for the maximum
// amount of time. May unlock and re-lock the global mutex.
flmCheckNUStructs( 0);
for( ;;)
{
// See if we already have the file open.
// May unlock and re-lock the global mutex.
if (RC_BAD( rc = flmFindFile( pszFilePath, pszDataDir, &pFile)))
{
goto Exit;
}
// Didn't find the file
if( !pFile)
{
break;
}
// See if file is being used, is being opened, or has any dependent
// files being used.
if (pFile->uiUseCount || (pFile->uiFlags & DBF_BEING_OPENED))
{
rc = RC_SET( FERR_IO_ACCESS_DENIED);
goto Exit;
}
// Free the FFILE structure. May temporarily unlock the global mutex.
// For this reason, we must call flmFindFile again (see above) after
// calling flmFreeFile.
flmFreeFile( pFile);
pFile = NULL;
}
// Allocate a new FFILE structure.
if (RC_BAD( rc = flmAllocFile( pszFilePath, pszDataDir, NULL, &pFile)))
{
goto Exit;
}
bNewFile = TRUE;
// Link the FDB to the file.
rc = flmLinkFdbToFile( pDb, pFile);
f_mutexUnlock( gv_FlmSysData.hShareMutex);
bMutexLocked = FALSE;
if (RC_BAD( rc))
{
goto Exit;
}
// If the file has not already been created, do so now.
// Determine what to set file block size to.
if (pCreateOpts != NULL)
{
pDb->pSFileHdl->SetBlockSize(
flmAdjustBlkSize( pCreateOpts->uiBlockSize));
pDb->pSFileHdl->SetDbVersion( pCreateOpts->uiVersionNum);
}
else
{
pDb->pSFileHdl->SetBlockSize( DEFAULT_BLKSIZ);
pDb->pSFileHdl->SetDbVersion( FLM_CURRENT_VERSION_NUM);
}
#ifdef FLM_USE_NICI
// Create a new F_CCS object for the database wrapping key if the new
// database version is at least ver 4.60
if (!pCreateOpts || pCreateOpts->uiVersionNum >= FLM_VER_4_60)
{
if ((pFile->pDbWrappingKey = f_new F_CCS) == NULL)
{
rc = RC_SET( FERR_MEM);
goto Exit;
}
if (RC_BAD( rc = pFile->pDbWrappingKey->init( TRUE,
FLM_NICI_AES)))
{
goto Exit;
}
// Only generate a key when this is not part of a rebuild operation or
// the original database version was less than 4.60
if (!pRebuildState ||
pRebuildState->pHdrInfo->FileHdr.uiVersionNum < FLM_VER_4_60)
{
if (RC_BAD( rc = pFile->pDbWrappingKey->generateWrappingKey()))
{
goto Exit;
}
}
else
{
if( RC_BAD( rc = pFile->pDbWrappingKey->setKeyFromStore(
&pRebuildState->pLogHdr[LOG_DATABASE_KEY],
FB2UW(&pRebuildState->pLogHdr[LOG_DATABASE_KEY_LEN]),
NULL, NULL, FALSE)))
{
goto Exit;
}
}
pFile->bHaveEncKey = TRUE;
}
#endif
if (RC_OK( gv_FlmSysData.pFileSystem->Exists( pszFilePath)))
{
rc = RC_SET( FERR_FILE_EXISTS);
goto Exit;
}
// Create the .db file.
if( RC_BAD( rc = pDb->pSFileHdl->CreateFile( 0)))
{
goto Exit;
}
bFileCreated = TRUE;
(void)flmStatGetDb( &pDb->Stats, pFile,
0, &pDb->pDbStats, NULL, NULL);
// We must have exclusive access. Create a lock file for that
// purpose, if there is not already a lock file.
if( RC_BAD( rc = flmGetExclAccess( pszFilePath, pDb)))
{
goto Exit;
}
if( RC_BAD( rc = flmInitNewFile( pDb, pszRflDir, pszDictFileName,
pszDictBuf, pCreateOpts, uiTransID)))
{
goto Exit;
}
// Set FFILE stuff to same state as a completed checkpoint.
pFile->uiFirstLogCPBlkAddress = 0;
pFile->uiLastCheckpointTime = (FLMUINT)FLM_GET_TIMER();
// Create a checkpoint thread
if( RC_BAD( rc = flmStartCPThread( pFile)))
{
goto Exit;
}
Exit:
if( bMutexLocked)
{
f_mutexUnlock( gv_FlmSysData.hShareMutex);
}
rc = flmCompleteOpenOrCreate( ppDb, rc, bNewFile, bAllocatedFdb);
if( RC_BAD( rc))
{
if( bFileCreated)
{
(void)gv_FlmSysData.pFileSystem->Delete( pszFilePath);
}
*ppDb = NULL;
}
return( rc);
}
/****************************************************************************
Desc: Create a database - initialize all physical areas & data dictionary.
****************************************************************************/
FSTATIC RCODE flmInitNewFile(
FDB * pDb,
const char * pszRflDir,
const char * pszDictFileName,
const char * pszDictBuf,
CREATE_OPTS * pCreateOpts,
FLMUINT uiTransID)
{
RCODE rc = FERR_OK;
FLMBYTE * pBuf = NULL;
FFILE * pFile = pDb->pFile;
FLMUINT uiBlkSize;
FLMUINT uiBufSize;
FLMUINT bTransStarted = FALSE;
// Determine what size of buffer to allocate.
if (pCreateOpts != NULL)
{
uiBlkSize = flmAdjustBlkSize( pCreateOpts->uiBlockSize);
}
else
{
uiBlkSize = DEFAULT_BLKSIZ;
}
// Initialize the database file header.
// Allocate a buffer to use - must be AT LEAST 2K.
uiBufSize = (FLMUINT)((uiBlkSize < 2048)
? (FLMUINT)2048
: (FLMUINT)uiBlkSize);
if (RC_BAD( rc = f_calloc( uiBufSize, &pBuf)))
{
goto Exit;
}
if (RC_BAD( rc = flmInitFileHdrs( pDb, pCreateOpts, uiBlkSize,
uiTransID, pBuf, uiBufSize)))
{
goto Exit;
}
// Free the buffer before returning.
f_free( &pBuf);
// Allocate the pRfl object. Could not do this until this point
// because we need to have the version number, block size, etc.
// setup in the pFile->FileHdr.
flmAssert( !pFile->pRfl);
if ((pFile->pRfl = f_new F_Rfl) == NULL)
{
rc = RC_SET( FERR_MEM);
goto Exit;
}
if (RC_BAD( rc = pFile->pRfl->setup( pFile, pszRflDir)))
{
goto Exit;
}
// Setup the FFILE's ECache object
flmAssert( pFile->pECacheMgr == NULL);
if( gv_FlmSysData.bOkToUseESM)
{
if( (pFile->pECacheMgr = f_new FlmECache) == NULL)
{
rc = RC_SET( FERR_MEM);
goto Exit;
}
if( !pFile->pECacheMgr->setupECache(
pFile->FileHdr.uiBlockSize, pFile->uiMaxFileSize))
{
pFile->pECacheMgr->Release();
pFile->pECacheMgr = NULL;
}
else
{
// Normally the ECacheMgr is set in flmLinkFdbToFile but
// we have to handle this special case here. When this
// FDB was linked there was no ECacheMgr.
flmAssert( pDb->pSFileHdl != NULL);
pDb->pSFileHdl->setECacheMgr( pFile->pECacheMgr);
}
}
// The following code starts an update transaction on the new DB so
// we can get it built.
if (RC_BAD( rc = flmBeginDbTrans( pDb, FLM_UPDATE_TRANS, 0)))
{
goto Exit;
}
bTransStarted = TRUE;
if( RC_BAD( rc = fdictCreate( pDb, pszDictFileName, pszDictBuf)))
{
goto Exit;
}
// Because the checkpoint thread has not yet been created,
// flmCommitDbTrans will force a checkpoint when it completes,
// ensuring a consistent database state.
if (RC_BAD( rc = flmCommitDbTrans( pDb, 0, TRUE)))
{
goto Exit;
}
bTransStarted = FALSE;
Exit:
// Free the temporary buffer, if one was allocated.
if (pBuf)
{
f_free( &pBuf);
}
if (bTransStarted)
{
(void)flmAbortDbTrans( pDb);
}
return( rc);
}
/***************************************************************************
Desc: This routine initializes a new database file. The first block
in the file is strictly for prefix and other fixed information
about the file. After the prefix, we initialize the fixed log
segment. Finally, we initialize the first database block --
which contains the physical file header record.
*****************************************************************************/
FSTATIC RCODE flmInitFileHdrs(
FDB * pDb,
CREATE_OPTS * pCreateOpts,
FLMUINT uiBlkSize,
FLMUINT uiTransID,
FLMBYTE * pInitBuf,
FLMUINT uiBufSize)
{
RCODE rc = FERR_OK;
FFILE_p pFile = pDb->pFile;
FLMBYTE * pucLastCommittedLogHdr;
FLMUINT uiLogicalEOF;
FLMUINT uiWriteBytes;
FLMUINT uiMinRflFileSize;
FLMUINT uiMaxRflFileSize;
FLMBYTE * pucBuf = NULL;
// Initialize the FFILE structure and first 2048 bytes/blk of the file.
f_memset( pInitBuf, 0, uiBlkSize);
flmInitFileHdrInfo( pCreateOpts, &pFile->FileHdr,
&pInitBuf [FLAIM_HEADER_START]);
if (pCreateOpts)
{
flmSetFilePrefix( pInitBuf, pCreateOpts->uiAppMajorVer,
pCreateOpts->uiAppMinorVer);
}
else
{
flmSetFilePrefix( pInitBuf, 0, 0);
}
if (RC_BAD( rc = pDb->pSFileHdl->WriteHeader( 0L, uiBlkSize,
pInitBuf, &uiWriteBytes)))
{
goto Exit;
}
// Set the logical EOF.
// Reserve two blocks for pre-4.3 - one for LFH, one for PCODE
// Reserve only room for LFH in 4.3 and above.
uiLogicalEOF = (FLMUINT)((pFile->FileHdr.uiVersionNum >=
FLM_VER_4_3)
? (FLMUINT)pFile->FileHdr.uiFirstLFHBlkAddr +
uiBlkSize
: (FLMUINT)pFile->FileHdr.uiFirstLFHBlkAddr +
uiBlkSize * 2);
// Initialize and output the log header.
pucLastCommittedLogHdr = &pFile->ucLastCommittedLogHdr [0];
f_memset( pucLastCommittedLogHdr, 0, LOG_HEADER_SIZE);
UD2FBA( (FLMUINT32)uiTransID,
&pucLastCommittedLogHdr [LOG_CURR_TRANS_ID]);
UD2FBA( (FLMUINT32)1, &pucLastCommittedLogHdr [LOG_RFL_FILE_NUM]);
// Putting a zero in this value tells the RFL code that the
// RFL file should be created - overwriting it if it already
// exists.
UD2FBA( (FLMUINT32)0, &pucLastCommittedLogHdr [LOG_RFL_LAST_TRANS_OFFSET]);
UD2FBA( (FLMUINT32)1, &pucLastCommittedLogHdr [LOG_RFL_LAST_CP_FILE_NUM]);
UD2FBA( (FLMUINT32)512, &pucLastCommittedLogHdr [LOG_RFL_LAST_CP_OFFSET]);
UD2FBA( (FLMUINT32)0, &pucLastCommittedLogHdr [LOG_LAST_RFL_FILE_DELETED]);
pucLastCommittedLogHdr [LOG_KEEP_RFL_FILES] =
(FLMBYTE)((pCreateOpts && pCreateOpts->bKeepRflFiles)
? (FLMBYTE)1
: (FLMBYTE)0);
pucLastCommittedLogHdr [LOG_AUTO_TURN_OFF_KEEP_RFL] = 0;
pucLastCommittedLogHdr [LOG_KEEP_ABORTED_TRANS_IN_RFL] =
(FLMBYTE)((pCreateOpts && pCreateOpts->bLogAbortedTransToRfl)
? (FLMBYTE)1
: (FLMBYTE)0);
UD2FBA( ((FLMUINT32)uiBlkSize),
&pucLastCommittedLogHdr [LOG_ROLLBACK_EOF]);
UD2FBA( (FLMUINT32)0,
&pucLastCommittedLogHdr [LOG_PL_FIRST_CP_BLOCK_ADDR]);
UW2FBA( (FLMUINT16) pDb->pFile->FileHdr.uiVersionNum,
&pucLastCommittedLogHdr [LOG_FLAIM_VERSION]);
uiMinRflFileSize = (FLMUINT)((pCreateOpts &&
pCreateOpts->uiMinRflFileSize)
? pCreateOpts->uiMinRflFileSize
: (FLMUINT)DEFAULT_MIN_RFL_FILE_SIZE);
if( pDb->pFile->FileHdr.uiVersionNum >= FLM_VER_4_3)
{
FLMUINT16 ui16Tmp;
uiMaxRflFileSize = (FLMUINT)((pCreateOpts &&
pCreateOpts->uiMaxRflFileSize)
? pCreateOpts->uiMaxRflFileSize
: (FLMUINT)DEFAULT_MAX_RFL_FILE_SIZE);
// Make sure the RFL size limits are valid.
// Maximum must be enough to hold at least one packet plus
// the RFL header. Minimum must not be greater than the
// maximum. NOTE: Minimum and maximum are allowed to be
// equal, but in all cases, maximum takes precedence over
// minimum. We will first NOT exceed the maximum. Then,
// if possible, we will go above the minimum.
if (uiMaxRflFileSize < RFL_MAX_PACKET_SIZE + 512)
{
uiMaxRflFileSize = RFL_MAX_PACKET_SIZE + 512;
}
if (uiMaxRflFileSize > gv_FlmSysData.uiMaxFileSize)
{
uiMaxRflFileSize = gv_FlmSysData.uiMaxFileSize;
}
if (uiMinRflFileSize > uiMaxRflFileSize)
{
uiMinRflFileSize = uiMaxRflFileSize;
}
UD2FBA( (FLMUINT32)uiMinRflFileSize,
&pucLastCommittedLogHdr [LOG_RFL_MIN_FILE_SIZE]);
UD2FBA( (FLMUINT32)uiMaxRflFileSize,
&pucLastCommittedLogHdr [LOG_RFL_MAX_FILE_SIZE]);
// Set the database serial number
f_createSerialNumber(
&pucLastCommittedLogHdr[ LOG_DB_SERIAL_NUM]);
// Set the "current" RFL serial number - will be stamped into the RFL
// file when it is first created.
f_createSerialNumber(
&pucLastCommittedLogHdr[ LOG_LAST_TRANS_RFL_SERIAL_NUM]);
// Set the "next" RFL serial number
f_createSerialNumber(
&pucLastCommittedLogHdr[ LOG_RFL_NEXT_SERIAL_NUM]);
// Set the incremental backup serial number and sequence number
f_createSerialNumber(
&pucLastCommittedLogHdr[ LOG_INC_BACKUP_SERIAL_NUM]);
UD2FBA( 1, &pucLastCommittedLogHdr[ LOG_INC_BACKUP_SEQ_NUM]);
// Set the file size limits
pFile->uiMaxFileSize = gv_FlmSysData.uiMaxFileSize;
ui16Tmp = (FLMUINT16)(gv_FlmSysData.uiMaxFileSize >> 16);
UW2FBA( ui16Tmp, &pucLastCommittedLogHdr [LOG_MAX_FILE_SIZE]);
}
else
{
UD2FBA( (FLMUINT32)uiMinRflFileSize,
&pucLastCommittedLogHdr [LOG_RFL_MIN_FILE_SIZE]);
pFile->uiMaxFileSize = MAX_FILE_SIZE_VER40;
}
// The defines better not have changed to be less than two blocks - in
// case we create more than one block below.
flmAssert( pFile->uiMaxFileSize >=
pFile->FileHdr.uiBlockSize * 2);
// Create the first block file.
if (RC_BAD( rc = pDb->pSFileHdl->CreateFile( 1)))
{
goto Exit;
}
// The following 0xFFFF initializations are done to make this four
// bytes compatible with how it used to be initialized. These bytes
// will ALWAYS be set to something else when the log header is
// written out.
UW2FBA( (FLMUINT16)0xFFFF,
&pucLastCommittedLogHdr [LOG_HDR_CHECKSUM]);
UD2FBA( (FLMUINT32)BT_END,
&pucLastCommittedLogHdr [LOG_PF_FIRST_BACKCHAIN]);
UD2FBA( (FLMUINT32)BT_END,
&pucLastCommittedLogHdr [LOG_PF_AVAIL_BLKS]);
UD2FBA( (FLMUINT32)uiLogicalEOF,
&pucLastCommittedLogHdr [LOG_LOGICAL_EOF]);
// Write out the database wrapping key
if (pDb->pFile->pDbWrappingKey)
{
FLMUINT32 ui32KeyLen = 0;
if (RC_BAD( rc = pDb->pFile->pDbWrappingKey->getKeyToStore(
&pucBuf, &ui32KeyLen, NULL, NULL, FALSE)))
{
goto Exit;
}
// IMPORTANT NOTE: pucBuf must be freed before going to Exit!!!
// Assert that the field in the log header is long enough to
// hold the key. Note: This test is only valid if the key
// field is the last one in the log header!!
flmAssert( ui32KeyLen <= (LOG_HEADER_SIZE - LOG_DATABASE_KEY));
UW2FBA(ui32KeyLen, &pucLastCommittedLogHdr[LOG_DATABASE_KEY_LEN]);
f_memcpy( &pucLastCommittedLogHdr[LOG_DATABASE_KEY], pucBuf,
ui32KeyLen);
f_free( &pucBuf);
}
if (RC_BAD( rc = flmWriteLogHdr( pDb->pDbStats, pDb->pSFileHdl,
pFile, pucLastCommittedLogHdr, NULL, TRUE)))
{
goto Exit;
}
// Copy the log header to the ucCheckpointLogHdr buffer.
// This is now the first official checkpoint version of the log
// header. It must be copied to the ucCheckpointLogHdr buffer so that
// it will not be lost in subsequent calls to flmWriteLogHdr.
f_memcpy( pFile->ucCheckpointLogHdr, pucLastCommittedLogHdr,
LOG_HEADER_SIZE);
// Initialize and output the first LFH block
f_memset( pInitBuf, 0, uiBlkSize);
SET_BH_ADDR( pInitBuf, pFile->FileHdr.uiFirstLFHBlkAddr);
pInitBuf [BH_TYPE] = BHT_LFH_BLK;
UD2FBA( (FLMUINT32)BT_END, &pInitBuf [BH_PREV_BLK]);
UD2FBA( (FLMUINT32)BT_END, &pInitBuf [BH_NEXT_BLK]);
UW2FBA( (FLMUINT16)BH_OVHD, &pInitBuf [BH_ELM_END]);
UD2FBA( (FLMUINT32)uiTransID, &pInitBuf [BH_TRANS_ID]);
BlkCheckSum( pInitBuf, CHECKSUM_SET,
pFile->FileHdr.uiFirstLFHBlkAddr,
uiBlkSize);
pDb->pSFileHdl->setMaxAutoExtendSize( pFile->uiMaxFileSize);
pDb->pSFileHdl->setExtendSize( pFile->uiFileExtendSize);
if (RC_BAD( rc = pDb->pSFileHdl->WriteBlock(
pFile->FileHdr.uiFirstLFHBlkAddr,
uiBlkSize, pInitBuf, uiBufSize, NULL,
&uiWriteBytes)))
{
goto Exit;
}
// Initialize and output the first pcode block.
if (pFile->FileHdr.uiVersionNum < FLM_VER_4_3)
{
FLMUINT uiPcodeAddr;
f_memset( pInitBuf, 0, uiBlkSize);
uiPcodeAddr = pFile->FileHdr.uiFirstLFHBlkAddr + uiBlkSize;
SET_BH_ADDR( pInitBuf, uiPcodeAddr);
pInitBuf [BH_TYPE] = BHT_PCODE_BLK;
UD2FBA( (FLMUINT32)BT_END, &pInitBuf [BH_PREV_BLK]);
UD2FBA( (FLMUINT32)BT_END, &pInitBuf [BH_NEXT_BLK]);
UW2FBA( (FLMUINT16)BH_OVHD, &pInitBuf [BH_ELM_END]);
UD2FBA( (FLMUINT32)uiTransID, &pInitBuf [BH_TRANS_ID]);
BlkCheckSum( pInitBuf, CHECKSUM_SET, uiPcodeAddr, uiBlkSize);
pDb->pSFileHdl->setMaxAutoExtendSize( pFile->uiMaxFileSize);
pDb->pSFileHdl->setExtendSize( pFile->uiFileExtendSize);
if (RC_BAD( rc = pDb->pSFileHdl->WriteBlock( uiPcodeAddr,
uiBlkSize, pInitBuf, uiBufSize, NULL,
&uiWriteBytes)))
{
goto Exit;
}
}
// Force things to disk.
if (RC_BAD( rc = pDb->pSFileHdl->Flush()))
{
goto Exit;
}
Exit:
if (pucBuf)
{
f_free( &pucBuf);
}
return( rc);
}