Files
mars-flaim/xflaim/util/viewblk.cpp
ahodgkinson 0f853ff59e Fixed problems with various utilities.
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@547 0109f412-320b-0410-ab79-c3e0c5ffbbe6
2006-06-12 20:10:52 +00:00

3629 lines
89 KiB
C++

//------------------------------------------------------------------------------
// Desc: This file contains routines for viewing blocks in the database.
//
// Tabs: 3
//
// Copyright (c) 1992-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: viewblk.cpp 3119 2006-01-19 13:39:12 -0700 (Thu, 19 Jan 2006) dsanders $
//------------------------------------------------------------------------------
#include "view.h"
FSTATIC void InitStatusBits(
FLMBYTE * pucStatusBytes);
FSTATIC void OrStatusBits(
FLMBYTE * pucDestStatusBytes,
FLMBYTE * pucSrcStatusBytes);
FSTATIC FLMBOOL TestStatusBit(
FLMBYTE * pucStatusBytes,
FLMINT iErrorCode);
FSTATIC FLMBOOL OutBlkHdrExpNum(
FLMUINT uiCol,
FLMUINT * puiRow,
eColorType uiBackColor,
eColorType uiForeColor,
eColorType uiUnselectBackColor,
eColorType uiUnselectForeColor,
eColorType uiSelectBackColor,
eColorType uiSelectForeColor,
FLMUINT uiLabelWidth,
FLMINT iLabelIndex,
FLMUINT uiFileNumber,
FLMUINT uiFileOffset,
void * pvcValue,
FLMUINT uiValueType,
FLMUINT uiModType,
FLMUINT64 ui64ExpNum,
FLMUINT64 ui64IgnoreExpNum,
FLMUINT uiOption);
FSTATIC void FormatBlkType(
char * pszTempBuf,
FLMUINT uiBlkType
);
FSTATIC FLMBOOL OutputStatus(
FLMUINT uiCol,
FLMUINT * puiRow,
eColorType uiBackColor,
eColorType uiForeColor,
FLMUINT uiLabelWidth,
FLMINT iLabelIndex,
FLMBYTE * pucStatusFlags
);
FSTATIC FLMBOOL OutputLeafElements(
FLMUINT uiCol,
FLMUINT * puiRow,
F_BTREE_BLK_HDR * pBlkHdr,
BLK_EXP_p pBlkExp,
FLMBYTE * pucBlkStatus,
FLMBOOL bStatusOnlyFlag);
FSTATIC FLMBOOL OutputDataOnlyElements(
FLMUINT uiCol,
FLMUINT * puiRow,
F_BLK_HDR * pBlkHdr,
BLK_EXP_p pBlkExp,
FLMBYTE * pucBlkStatus,
FLMBOOL bStatusOnlyFlag);
FSTATIC FLMBOOL OutputNonLeafElements(
FLMUINT uiCol,
FLMUINT * puiRow,
F_BTREE_BLK_HDR * pBlkHdr,
BLK_EXP_p pBlkExp,
FLMBYTE * pucBlkStatus,
FLMBOOL bStatusOnlyFlag);
FSTATIC FLMBOOL OutputDomNode(
FLMUINT uiCol,
FLMUINT * puiRow,
eColorType uiBackColor,
eColorType uiForeColor,
FLMBYTE * pucVal,
STATE_INFO * pStateInfo);
FSTATIC void SetSearchTopBottom( void);
FSTATIC void GetElmInfo(
FLMBYTE * pucEntry,
F_BTREE_BLK_HDR * pBlkHdr,
STATE_INFO * pStateInfo);
extern FLMUINT gv_uiTopLine;
extern FLMUINT gv_uiBottomLine;
/********************************************************************
Desc: Initialize status bits
*********************************************************************/
FSTATIC void InitStatusBits(
FLMBYTE * pucStatusBytes
)
{
if (pucStatusBytes)
{
f_memset( pucStatusBytes, 0, NUM_STATUS_BYTES);
}
}
/********************************************************************
Desc: OR together two sets of status bytes
*********************************************************************/
FSTATIC void OrStatusBits(
FLMBYTE * pucDestStatusBytes,
FLMBYTE * pucSrcStatusBytes
)
{
FLMUINT uiLoop;
if (pucDestStatusBytes && pucSrcStatusBytes)
{
for (uiLoop = 0; uiLoop < NUM_STATUS_BYTES; uiLoop++)
{
pucDestStatusBytes [uiLoop] |= pucSrcStatusBytes [uiLoop];
}
}
}
/********************************************************************
Desc: TestStatusBit
*********************************************************************/
FSTATIC FLMBOOL TestStatusBit(
FLMBYTE * pucStatusBytes,
FLMINT iErrorCode
)
{
if (!pucStatusBytes)
{
return( FALSE);
}
else
{
return( (FLMBOOL)(pucStatusBytes [(iErrorCode - 1) / 8] &
(FLMBYTE)((FLMBYTE)0x80 >> (FLMBYTE)((iErrorCode - 1) % 8))
? TRUE
: FALSE));
}
}
/***************************************************************************
Desc: This routine outputs all of the status bits which were set for
a block. Each error discovered in a block will be displayed on
a separate line.
*****************************************************************************/
FSTATIC FLMBOOL OutputStatus(
FLMUINT uiCol,
FLMUINT * puiRow,
eColorType uiBackColor,
eColorType uiForeColor,
FLMUINT uiLabelWidth,
FLMINT iLabelIndex,
FLMBYTE * pucStatusFlags
)
{
FLMBOOL bOk = FALSE;
FLMUINT uiRow = *puiRow;
FLMINT iError;
FLMBOOL bHadError = FALSE;
// Output each error on a separate line
if (pucStatusFlags)
{
for (iError = 0; iError < FLM_NUM_CORRUPT_ERRORS; iError++)
{
if (TestStatusBit( pucStatusFlags, iError))
{
bHadError = TRUE;
if (!ViewAddMenuItem( iLabelIndex, uiLabelWidth,
VAL_IS_ERR_INDEX, (FLMUINT64)iError, 0,
0, VIEW_INVALID_FILE_OFFSET, 0, MOD_DISABLED,
uiCol, uiRow++, 0,
FLM_RED, FLM_LIGHTGRAY,
FLM_RED, FLM_LIGHTGRAY))
{
goto Exit;
}
// Set iLabelIndex to -1 so that it will not be displayed after
// the first one.
iLabelIndex = -1;
}
}
}
// If there were no errors in the block, just output an OK status
if (!bHadError)
{
if (!ViewAddMenuItem( iLabelIndex, uiLabelWidth,
VAL_IS_LABEL_INDEX, (FLMUINT64)LBL_OK, 0,
0, VIEW_INVALID_FILE_OFFSET, 0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
*puiRow = uiRow;
bOk = TRUE;
Exit:
return( bOk);
}
/***************************************************************************
Desc: This routine reads into memory a database block. It will also
allocate memory to hold the block if necessary. The block will
also be decrypted if necessary.
*****************************************************************************/
FLMBOOL ViewBlkRead(
FLMUINT uiBlkAddress,
F_BLK_HDR ** ppBlkHdr,
FLMBOOL bOkToConvert,
FLMUINT uiReadLen,
FLMUINT32 * pui32CalcCRC,
FLMUINT32 * pui32BlkCRC,
FLMUINT * puiBytesRead,
FLMBOOL bShowPartialReadError
)
{
FLMBOOL bOk = FALSE;
RCODE rc;
F_BLK_HDR * pBlkHdr;
char szErrMsg [80];
FLMUINT uiBlkEnd;
FLMUINT16 ui16BlkBytesAvail;
// First allocate memory to read the block into
// if not already allocated
if (!(*ppBlkHdr))
{
if (RC_BAD( rc = f_alloc( uiReadLen, ppBlkHdr)))
{
ViewShowRCError( "allocating memory to read block", rc);
goto Exit;
}
}
pBlkHdr = *ppBlkHdr;
// Read the block into memory
if (RC_BAD( rc = gv_pSFileHdl->readBlock( uiBlkAddress, uiReadLen,
pBlkHdr, puiBytesRead)))
{
if (rc == NE_XFLM_IO_END_OF_FILE)
{
rc = NE_XFLM_OK;
f_memset( (FLMBYTE *)pBlkHdr + *puiBytesRead, 0xEE,
uiReadLen - *puiBytesRead);
if (bShowPartialReadError)
{
if (!(*puiBytesRead))
{
ViewShowRCError( "reading block", NE_XFLM_IO_END_OF_FILE);
goto Exit;
}
else if (*puiBytesRead < uiReadLen)
{
f_sprintf( szErrMsg,
"Only %u bytes of data were read (requested %u)",
(unsigned)*puiBytesRead, (unsigned)uiReadLen);
ViewShowError( szErrMsg);
}
}
}
else
{
ViewShowRCError( "reading block", rc);
goto Exit;
}
}
// Calculate the CRC on the block.
if (bOkToConvert)
{
if (pui32CalcCRC)
{
ui16BlkBytesAvail = pBlkHdr->ui16BlkBytesAvail;
if (blkIsNonNativeFormat( pBlkHdr))
{
convert16( &ui16BlkBytesAvail);
}
if( ui16BlkBytesAvail > gv_ViewDbHdr.ui16BlockSize)
{
*pui32CalcCRC = 0;
}
else
{
uiBlkEnd = (blkIsNewBTree( pBlkHdr)
? gv_ViewDbHdr.ui16BlockSize
: gv_ViewDbHdr.ui16BlockSize - (FLMUINT)ui16BlkBytesAvail);
*pui32CalcCRC = calcBlkCRC( pBlkHdr, uiBlkEnd);
}
}
if (blkIsNonNativeFormat( pBlkHdr))
{
convertBlk( (FLMUINT)gv_ViewDbHdr.ui16BlockSize, pBlkHdr);
}
if (pui32BlkCRC)
{
*pui32BlkCRC = pBlkHdr->ui32BlkCRC;
}
}
bOk = TRUE;
Exit:
return( bOk);
}
/***************************************************************************
Desc: This routine searches through the LFH blocks searching for the
LFH of a particular logical file.
*****************************************************************************/
FLMBOOL ViewGetLFH(
FLMUINT uiLfNum,
eLFileType eLfType,
F_LF_HDR * pLfHdr,
FLMUINT * puiFileOffset)
{
FLMUINT uiBlkAddress;
FLMUINT uiBlkCount = 0;
F_BLK_HDR * pBlkHdr = NULL;
F_LF_HDR * pTmpLfHdr;
FLMUINT uiEndOfBlock;
FLMUINT uiPos;
FLMUINT uiBytesRead;
FLMBOOL bGotLFH = FALSE;
// Read the LFH blocks and get the information needed
// If we read too many, the file is probably corrupt.
*puiFileOffset = 0;
uiBlkAddress = (FLMUINT)gv_ViewDbHdr.ui32FirstLFBlkAddr;
while (uiBlkAddress)
{
if (!ViewBlkRead( uiBlkAddress, &pBlkHdr, TRUE,
(FLMUINT)gv_ViewDbHdr.ui16BlockSize,
NULL, NULL, &uiBytesRead, FALSE) ||
!uiBytesRead)
{
break;
}
// Count the blocks read to prevent too many from being read.
// We don't want to get into an infinite loop if the database
// is corrupted.
uiBlkCount++;
// Search through the block for the particular LFH which matches
// the one we are looking for.
if (uiBytesRead <= SIZEOF_STD_BLK_HDR)
{
uiEndOfBlock = SIZEOF_STD_BLK_HDR;
}
else
{
uiEndOfBlock = blkGetEnd( (FLMUINT)gv_ViewDbHdr.ui16BlockSize,
SIZEOF_STD_BLK_HDR, pBlkHdr);
if (uiEndOfBlock > uiBytesRead)
{
uiEndOfBlock = uiBytesRead;
}
}
uiPos = SIZEOF_STD_BLK_HDR;
pTmpLfHdr = (F_LF_HDR *)((FLMBYTE *)pBlkHdr + SIZEOF_STD_BLK_HDR);
while (uiPos < uiEndOfBlock)
{
// See if we got the one we wanted
if (pTmpLfHdr->ui32LfType != XFLM_LF_INVALID &&
(FLMUINT)pTmpLfHdr->ui32LfNumber == uiLfNum &&
(FLMUINT)pTmpLfHdr->ui32LfType == (FLMUINT)eLfType)
{
f_memcpy( pLfHdr, pTmpLfHdr, sizeof( F_LF_HDR));
bGotLFH = TRUE;
*puiFileOffset = uiBlkAddress + uiPos;
break;
}
uiPos += sizeof( F_LF_HDR);
pTmpLfHdr++;
}
// If we didn't end right on end of block, return
if (uiPos != uiEndOfBlock || bGotLFH)
{
break;
}
// If we have traversed too many blocks, things are probably corrupt
if (uiBlkCount > 1000)
{
break;
}
if (F_BLK_HDR_ui32NextBlkInChain_OFFSET + 4 <= uiBytesRead)
{
uiBlkAddress = pBlkHdr->ui32NextBlkInChain;
}
else
{
uiBlkAddress = 0;
}
}
// Be sure to free the block -- if one was allocated
f_free( &pBlkHdr);
return( bGotLFH);
}
/***************************************************************************
Desc: This routine attempts to find an LFH for a particular logical
file. It then extracts the name from the LFH.
*****************************************************************************/
FLMBOOL ViewGetLFName(
char * pszName,
FLMUINT uiLfNum,
eLFileType eLfType,
F_LF_HDR * pLfHdr,
FLMUINT * puiFileOffset)
{
f_sprintf( pszName, "lfNum=%u", (unsigned)uiLfNum);
if (!uiLfNum || !ViewGetLFH( uiLfNum, eLfType, pLfHdr, puiFileOffset))
{
*puiFileOffset = 0;
f_memset( pLfHdr, 0, sizeof( F_LF_HDR));
return( FALSE);
}
return( TRUE);
}
/***************************************************************************
Desc: This routine outputs one of the number fields in the block
header. It checks the number against an expected value, and if
the number does not match the expected value also outputs the
value which was expected. This routine is used to output values
in the block header where we expect certain values.
*****************************************************************************/
FSTATIC FLMBOOL OutBlkHdrExpNum(
FLMUINT uiCol,
FLMUINT * puiRow,
eColorType uiBackColor,
eColorType uiForeColor,
eColorType uiUnselectBackColor,
eColorType uiUnselectForeColor,
eColorType uiSelectBackColor,
eColorType uiSelectForeColor,
FLMUINT uiLabelWidth,
FLMINT iLabelIndex,
FLMUINT uiFileNumber,
FLMUINT uiFileOffset,
void * pvValue,
FLMUINT uiValueType,
FLMUINT uiModType,
FLMUINT64 ui64ExpNum,
FLMUINT64 ui64IgnoreExpNum,
FLMUINT uiOption)
{
FLMBOOL bOk = FALSE;
FLMUINT uiRow = *puiRow;
FLMUINT64 ui64Num = 0;
if (!uiOption)
{
uiUnselectBackColor = uiSelectBackColor = uiBackColor;
uiUnselectForeColor = uiSelectForeColor = uiForeColor;
}
switch (uiModType & 0x0F)
{
case MOD_FLMUINT64:
ui64Num = *((FLMUINT64 *)pvValue);
break;
case MOD_FLMUINT32:
ui64Num = (FLMUINT64)(*((FLMUINT32 *)pvValue));
break;
case MOD_FLMUINT16:
ui64Num = (FLMUINT64)(*((FLMUINT16 *)pvValue));
break;
case MOD_FLMBYTE:
ui64Num = (FLMUINT64)(*((FLMUINT8 *)pvValue));
break;
}
if (!ViewAddMenuItem( iLabelIndex, uiLabelWidth,
uiValueType, ui64Num, 0,
uiFileNumber, uiFileOffset, 0,
uiModType | MOD_NATIVE,
uiCol, uiRow++, uiOption,
uiUnselectBackColor, uiUnselectForeColor,
uiSelectBackColor, uiSelectForeColor))
{
goto Exit;
}
if (ui64ExpNum != ui64IgnoreExpNum && ui64Num != ui64ExpNum)
{
if (!ViewAddMenuItem( LBL_EXPECTED, 0,
uiValueType, ui64ExpNum, 0,
0, VIEW_INVALID_FILE_OFFSET, 0, MOD_DISABLED,
uiCol + uiLabelWidth + 1, uiRow++, 0,
FLM_RED, FLM_LIGHTGRAY,
FLM_RED, FLM_LIGHTGRAY))
{
goto Exit;
}
}
*puiRow = uiRow;
bOk = TRUE;
Exit:
return( bOk);
}
/***************************************************************************
Desc: This routine formats a block's type into ASCII.
*****************************************************************************/
FSTATIC void FormatBlkType(
char * pszTempBuf,
FLMUINT uiBlkType
)
{
switch (uiBlkType)
{
case BT_FREE:
f_strcpy( pszTempBuf, "Free");
break;
case BT_LEAF:
f_strcpy( pszTempBuf, "Leaf");
break;
case BT_NON_LEAF:
f_strcpy( pszTempBuf, "Non-Leaf");
break;
case BT_NON_LEAF_COUNTS:
f_strcpy( pszTempBuf, "Non-Leaf /w Counts");
break;
case BT_LEAF_DATA:
f_strcpy( pszTempBuf, "Leaf /w Data");
break;
case BT_DATA_ONLY:
f_strcpy( pszTempBuf, "Data Only");
break;
case BT_LFH_BLK:
f_strcpy( pszTempBuf, "LFH");
break;
default:
f_sprintf( pszTempBuf,
"Unknown Type: %u", (unsigned)uiBlkType);
break;
}
}
/***************************************************************************
Desc: This routine outputs a block's header.
*****************************************************************************/
FLMBOOL ViewOutBlkHdr(
FLMUINT uiCol,
FLMUINT * puiRow,
F_BLK_HDR * pBlkHdr,
BLK_EXP_p pBlkExp,
FLMBYTE * pucBlkStatus,
FLMUINT32 ui32CalcCRC,
FLMUINT32 ui32BlkCRC
)
{
FLMBOOL bOk = FALSE;
FLMUINT uiLabelWidth = 35;
FLMUINT uiRow = *puiRow;
char szTempBuf [80];
FLMUINT uiBlkAddress;
FLMUINT uiEndOfBlock;
FLMUINT uiBytesUsed;
FLMUINT uiPercentFull;
FLMUINT uiOption;
eColorType uiBackColor = FLM_BLACK;
eColorType uiForeColor = FLM_LIGHTGRAY;
eColorType uiUnselectBackColor = FLM_BLACK;
eColorType uiUnselectForeColor = FLM_WHITE;
eColorType uiSelectBackColor = FLM_BLUE;
eColorType uiSelectForeColor = FLM_WHITE;
F_LF_HDR lfHdr;
char szLfName [80];
FLMUINT uiLfNum;
eLFileType eLfType;
FLMUINT uiTempFileOffset;
// Output the block Header address
if (!OutBlkHdrExpNum( uiCol, &uiRow, FLM_RED, FLM_LIGHTGRAY,
FLM_RED, FLM_WHITE, uiSelectBackColor, uiSelectForeColor,
uiLabelWidth, LBL_BLOCK_ADDRESS_BLOCK_HEADER,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr),
&pBlkHdr->ui32BlkAddr,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
MOD_FLMUINT32 | MOD_HEX | MOD_NATIVE,
(FLMUINT64)pBlkExp->uiBlkAddr, 0, 0))
{
goto Exit;
}
// Adjust column so rest of header is indented
uiCol += 2;
uiLabelWidth -= 2;
// Output the previous block address
if (!pBlkHdr->ui32PrevBlkInChain)
{
uiOption = 0;
}
else
{
uiOption = PREV_BLOCK_OPTION;
}
if (!OutBlkHdrExpNum( uiCol, &uiRow, uiBackColor, uiForeColor,
uiUnselectBackColor, uiUnselectForeColor,
uiSelectBackColor, uiSelectForeColor,
uiLabelWidth, LBL_PREVIOUS_BLOCK_ADDRESS,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BLK_HDR_ui32PrevBlkInChain_OFFSET,
&pBlkHdr->ui32PrevBlkInChain,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
MOD_FLMUINT32 | MOD_HEX | MOD_NATIVE,
(FLMUINT64)pBlkExp->uiPrevAddr, 0xFFFFFFFF, uiOption))
{
goto Exit;
}
// Output the next block address
if (!pBlkHdr->ui32NextBlkInChain)
{
uiOption = 0;
}
else
{
uiOption = NEXT_BLOCK_OPTION;
}
if (!OutBlkHdrExpNum( uiCol, &uiRow, uiBackColor, uiForeColor,
uiUnselectBackColor, uiUnselectForeColor,
uiSelectBackColor, uiSelectForeColor,
uiLabelWidth, LBL_NEXT_BLOCK_ADDRESS,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BLK_HDR_ui32NextBlkInChain_OFFSET,
&pBlkHdr->ui32NextBlkInChain,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
MOD_FLMUINT32 | MOD_HEX | MOD_NATIVE,
(FLMUINT64)pBlkExp->uiNextAddr, 0xFFFFFFFF, uiOption))
{
goto Exit;
}
// Output the prior block image address
uiBlkAddress = (FLMUINT)pBlkHdr->ui32PriorBlkImgAddr;
if (uiBlkAddress == 0 ||
pBlkHdr->ui64TransID <= gv_ViewDbHdr.ui64CurrTransID)
{
uiOption = 0;
}
else
{
uiOption = PREV_BLOCK_IMAGE_OPTION;
}
if (!ViewAddMenuItem( LBL_OLD_BLOCK_IMAGE_ADDRESS, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
(FLMUINT64)uiBlkAddress, 0,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BLK_HDR_ui32PriorBlkImgAddr_OFFSET, 0,
MOD_FLMUINT32 | MOD_HEX | MOD_NATIVE,
uiCol, uiRow++, uiOption,
(!uiOption ? uiBackColor : uiUnselectBackColor),
(!uiOption ? uiForeColor : uiUnselectForeColor),
(!uiOption ? uiBackColor : uiSelectBackColor),
(!uiOption ? uiForeColor : uiSelectForeColor)))
{
goto Exit;
}
// Output the block transaction ID
if (!ViewAddMenuItem( LBL_BLOCK_TRANS_ID, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
pBlkHdr->ui64TransID, 0,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BLK_HDR_ui64TransID_OFFSET, 0,
MOD_FLMUINT32 | MOD_DECIMAL | MOD_NATIVE,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output the block CRC
if (!OutBlkHdrExpNum( uiCol, &uiRow, uiBackColor, uiForeColor,
uiUnselectBackColor, uiUnselectForeColor,
uiSelectBackColor, uiSelectForeColor,
uiLabelWidth, LBL_BLOCK_CRC,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BLK_HDR_ui32BlkCRC_OFFSET,
&ui32BlkCRC,
VAL_IS_NUMBER | DISP_DECIMAL,
MOD_FLMUINT32 | MOD_DECIMAL | MOD_NATIVE,
(FLMUINT64)ui32CalcCRC, 0, 0))
{
return( 0);
}
// Output the available bytes in the block
if (!ViewAddMenuItem( LBL_BLOCK_BYTES_AVAIL, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)pBlkHdr->ui16BlkBytesAvail, 0,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BLK_HDR_ui16BlkBytesAvail_OFFSET, 0,
MOD_FLMUINT16 | MOD_DECIMAL | MOD_NATIVE,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output the heap bytes in the block
if ((pBlkHdr->ui8BlkType == BT_LEAF) ||
(pBlkHdr->ui8BlkType == BT_LEAF_DATA) ||
(pBlkHdr->ui8BlkType == BT_NON_LEAF) ||
(pBlkHdr->ui8BlkType == BT_NON_LEAF_COUNTS))
{
if (!ViewAddMenuItem( LBL_BLOCK_HEAP_SIZE, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)((F_BTREE_BLK_HDR *)pBlkHdr)->ui16HeapSize, 0,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BTREE_BLK_HDR_ui16HeapSize_OFFSET, 0,
MOD_FLMUINT16 | MOD_DECIMAL | MOD_NATIVE,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
uiEndOfBlock = blkGetEnd( (FLMUINT)gv_ViewDbHdr.ui16BlockSize,
blkHdrSize( pBlkHdr), pBlkHdr);
// Output the percent full
if (blkIsNewBTree( pBlkHdr))
{
uiBytesUsed = gv_ViewDbHdr.ui16BlockSize -
pBlkHdr->ui16BlkBytesAvail - blkHdrSize( pBlkHdr);
}
else
{
uiBytesUsed = uiEndOfBlock - blkHdrSize( pBlkHdr);
}
if (!uiBytesUsed || uiEndOfBlock < blkHdrSize( pBlkHdr))
{
uiPercentFull = 0;
}
else if (uiEndOfBlock > (FLMUINT)gv_ViewDbHdr.ui16BlockSize)
{
uiPercentFull = 100;
}
else
{
uiPercentFull = ((FLMUINT)(uiBytesUsed) * (FLMUINT)(100)) /
((FLMUINT)(gv_ViewDbHdr.ui16BlockSize) -
blkHdrSize( pBlkHdr));
}
if (!ViewAddMenuItem( LBL_PERCENT_FULL, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)uiPercentFull, 0,
0, VIEW_INVALID_FILE_OFFSET, 0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
if (!ViewAddMenuItem( LBL_BLOCK_END, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
(FLMUINT64)(FSGetFileOffset( pBlkExp->uiBlkAddr) + uiEndOfBlock),
0,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) + uiEndOfBlock,
0, MOD_DISABLED, uiCol, uiRow++,
0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output block flags here
if (pBlkHdr->ui8BlkFlags & BLK_FORMAT_IS_LITTLE_ENDIAN)
{
f_strcpy( szTempBuf, "Little-Endian");
}
else
{
f_strcpy( szTempBuf, "Big-Endian");
}
if (pBlkHdr->ui8BlkFlags & BLK_IS_BEFORE_IMAGE)
{
f_strcpy( &szTempBuf [f_strlen( szTempBuf)], ", Before-Image");
}
if (!ViewAddMenuItem( LBL_BLOCK_FLAGS, uiLabelWidth,
VAL_IS_TEXT_PTR,
(FLMUINT)&szTempBuf[0], 0,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BLK_HDR_ui8BlkFlags_OFFSET, 0,
MOD_FLMBYTE | MOD_HEX | MOD_NATIVE,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output the block type
FormatBlkType( szTempBuf, (FLMUINT)pBlkHdr->ui8BlkType);
if (pBlkHdr->ui8BlkType != (FLMUINT8)pBlkExp->uiType)
{
f_strcpy( &szTempBuf [f_strlen( szTempBuf)], ", Expecting ");
FormatBlkType( &szTempBuf [f_strlen( szTempBuf)], pBlkExp->uiType);
}
if (!ViewAddMenuItem( LBL_BLOCK_TYPE, uiLabelWidth,
VAL_IS_TEXT_PTR,
(FLMUINT)(&szTempBuf [0]), 0,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BLK_HDR_ui8BlkType_OFFSET, 0,
MOD_FLMBYTE | MOD_HEX | MOD_NATIVE,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
if (blkIsBTree( pBlkHdr) && (pBlkHdr->ui8BlkType != BT_DATA_ONLY))
{
// Output the logical file this block belongs to - if any
uiLfNum = (FLMUINT)(((F_BTREE_BLK_HDR *)pBlkHdr)->ui16LogicalFile);
eLfType = getBlkLfType( (F_BTREE_BLK_HDR *)pBlkHdr);
if (!ViewGetLFName( szLfName, uiLfNum, eLfType,
&lfHdr, &uiTempFileOffset))
{
eLfType = XFLM_LF_INVALID;
uiOption = 0;
}
else
{
if (eLfType == XFLM_LF_INDEX)
{
uiOption = LOGICAL_INDEX_OPTION | uiLfNum;
}
else
{
uiOption = LOGICAL_CONTAINER_OPTION | uiLfNum;
}
}
if (pBlkExp->uiLfNum && uiLfNum != pBlkExp->uiLfNum)
{
f_sprintf( (char *)szTempBuf, "%s (Expected %u)", szLfName,
(unsigned)pBlkExp->uiLfNum);
}
else
{
f_strcpy( szTempBuf, szLfName);
}
if (!ViewAddMenuItem( LBL_BLOCK_LOGICAL_FILE_NAME, uiLabelWidth,
VAL_IS_TEXT_PTR,
(FLMUINT)((FLMBYTE *)(&szTempBuf [0])), 0,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BTREE_BLK_HDR_ui16LogicalFile_OFFSET, 0,
MOD_FLMUINT16 | MOD_DECIMAL | MOD_NATIVE,
uiCol, uiRow++, uiOption,
(!uiOption ? uiBackColor : uiUnselectBackColor),
(!uiOption ? uiForeColor : uiUnselectForeColor),
(!uiOption ? uiBackColor : uiSelectBackColor),
(!uiOption ? uiForeColor : uiSelectForeColor)))
{
goto Exit;
}
// Output the logical file type
FormatLFType( szTempBuf, eLfType);
if (!ViewAddMenuItem( LBL_BLOCK_LOGICAL_FILE_TYPE, uiLabelWidth,
VAL_IS_TEXT_PTR,
(FLMUINT)((FLMBYTE *)(&szTempBuf [0])), 0,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BTREE_BLK_HDR_ui8BTreeFlags_OFFSET, 0,
MOD_FLMBYTE | MOD_HEX | MOD_NATIVE,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output number of keys
if (!ViewAddMenuItem( LBL_BLOCK_NUM_KEYS, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)(((F_BTREE_BLK_HDR *)pBlkHdr)->ui16NumKeys), 0,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BTREE_BLK_HDR_ui16NumKeys_OFFSET, 0,
MOD_FLMUINT16 | MOD_DECIMAL | MOD_NATIVE,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output block level
if (!OutBlkHdrExpNum( uiCol, &uiRow,
uiBackColor, uiForeColor,
uiUnselectBackColor, uiUnselectForeColor,
uiSelectBackColor, uiSelectForeColor,
uiLabelWidth, LBL_B_TREE_LEVEL,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BTREE_BLK_HDR_ui8BlkLevel_OFFSET,
&(((F_BTREE_BLK_HDR *)pBlkHdr)->ui8BlkLevel),
VAL_IS_NUMBER | DISP_DECIMAL,
MOD_FLMBYTE | MOD_DECIMAL | MOD_NATIVE,
(FLMUINT64)pBlkExp->uiLevel, (FLMUINT64)0xFF, 0))
{
goto Exit;
}
// Output if block is a root block
if (!ViewAddMenuItem( LBL_BLOCK_ROOT, uiLabelWidth,
VAL_IS_LABEL_INDEX,
(FLMUINT64)(isRootBlk( (F_BTREE_BLK_HDR *)pBlkHdr)
? (FLMUINT64)LBL_YES
: (FLMUINT64)LBL_NO), 0,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BTREE_BLK_HDR_ui8BTreeFlags_OFFSET, 0,
MOD_FLMBYTE | MOD_HEX | MOD_NATIVE,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output if block is encrypted
if (!ViewAddMenuItem( LBL_BLOCK_ENCRYPTED, uiLabelWidth,
VAL_IS_LABEL_INDEX,
(FLMUINT64)(isEncryptedBlk( pBlkHdr)
? (FLMUINT64)LBL_YES
: (FLMUINT64)LBL_NO), 0,
FSGetFileNumber( pBlkExp->uiBlkAddr),
FSGetFileOffset( pBlkExp->uiBlkAddr) +
F_BTREE_BLK_HDR_ui8BTreeFlags_OFFSET, 0,
MOD_FLMBYTE | MOD_HEX | MOD_NATIVE,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
// Output the flags which indicate the state of the block
if (!OutputStatus( uiCol, &uiRow, uiBackColor, uiForeColor,
uiLabelWidth, LBL_BLOCK_STATUS, pucBlkStatus))
{
goto Exit;
}
*puiRow = uiRow + 1;
bOk = TRUE;
Exit:
return( bOk);
}
/***************************************************************************
Desc: This routine displays a block in the AVAIL list.
*****************************************************************************/
FLMBOOL ViewAvailBlk(
FLMUINT uiReadAddress,
FLMUINT uiBlkAddress,
F_BLK_HDR ** ppBlkHdr,
BLK_EXP_p pBlkExp
)
{
FLMBOOL bOk = FALSE;
FLMUINT uiRow;
FLMUINT uiCol;
F_BLK_HDR * pBlkHdr;
FLMBYTE ucBlkStatus [NUM_STATUS_BYTES];
STATE_INFO StateInfo;
// FLMBOOL bStateInitialized = FALSE;
// BLOCK_INFO BlockInfo;
// FLMINT iErrorCode;
FLMUINT32 ui32CalcCRC;
FLMUINT32 ui32BlkCRC;
FLMUINT uiBytesRead;
// Read the block into memory
if (!ViewBlkRead( uiReadAddress, ppBlkHdr, TRUE,
(FLMUINT)gv_ViewDbHdr.ui16BlockSize,
&ui32CalcCRC, &ui32BlkCRC, &uiBytesRead, TRUE))
{
goto Exit;
}
pBlkHdr = *ppBlkHdr;
ViewMenuInit( "AVAIL Block");
// Output the block header first
uiRow = 0;
uiCol = 5;
pBlkExp->uiType = BT_FREE;
pBlkExp->uiLfNum = 0;
pBlkExp->uiBlkAddr = uiBlkAddress;
pBlkExp->uiLevel = 0xFF;
// Setup the STATE variable for processing through the block
InitStatusBits( ucBlkStatus);
#if 0
flmInitReadState( &StateInfo, &bStateInitialized,
(FLMUINT)gv_ViewDbHdr.ui32DbVersion,
(gv_bViewDbInitialized)
? gv_hViewDb
: NULL,
NULL, 0, BT_FREE, NULL);
#endif
StateInfo.ui32BlkAddress = (FLMUINT32)uiBlkAddress;
StateInfo.pBlkHdr = pBlkHdr;
#if 0
if ((iErrorCode = flmVerifyBlockHeader( &StateInfo, &BlockInfo,
(FLMUINT)gv_ViewDbHdr.ui16BlockSize,
pBlkExp->uiNextAddr,
0xFFFFFFFF,
(FLMBOOL)(StateInfo.pDb != NULL
? TRUE
: FALSE))) != 0)
{
SetStatusBit( ucBlkStatus, iErrorCode);
}
#endif
if (!ViewOutBlkHdr( uiCol, &uiRow, pBlkHdr, pBlkExp, ucBlkStatus,
ui32CalcCRC, ui32BlkCRC))
{
goto Exit;
}
bOk = TRUE;
Exit:
return( bOk);
}
/***************************************************************************
Desc: This routine outputs a stream of FLMBYTEs in hex format. This
routine is used to output key values and records within an
element.
*****************************************************************************/
FLMBOOL OutputHexValue(
FLMUINT uiCol,
FLMUINT * puiRow,
eColorType uiBackColor,
eColorType uiForeColor,
FLMINT iLabelIndex,
FLMUINT uiFileNumber,
FLMUINT uiFileOffset,
FLMBYTE * pucVal,
FLMUINT uiValLen,
FLMBOOL bCopyVal)
{
FLMBOOL bOk = FALSE;
FLMUINT uiRow = *puiRow;
FLMUINT uiBytesPerLine = MAX_HORIZ_SIZE( uiCol + 3);
FLMBOOL bFirstTime = TRUE;
FLMUINT uiBytesProcessed = 0;
FLMUINT uiNumBytes;
while (uiBytesProcessed < uiValLen)
{
if ((uiNumBytes = uiValLen - uiBytesProcessed) > uiBytesPerLine)
{
uiNumBytes = uiBytesPerLine;
}
// Output the line
if (bFirstTime)
{
if (!ViewAddMenuItem( iLabelIndex, 0,
VAL_IS_EMPTY, 0, 0,
uiFileNumber, uiFileOffset, 0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
bFirstTime = FALSE;
uiCol += 2;
}
if (!ViewAddMenuItem( -1, 0,
(FLMBYTE)((bCopyVal)
? (FLMBYTE)VAL_IS_BINARY
: (FLMBYTE)VAL_IS_BINARY_PTR),
(FLMUINT)pucVal, uiNumBytes,
uiFileNumber, uiFileOffset, uiNumBytes, MOD_BINARY,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
uiFileOffset += uiNumBytes;
uiBytesProcessed += uiNumBytes;
pucVal += uiNumBytes;
}
*puiRow = uiRow;
bOk = TRUE;
Exit:
return( bOk);
}
/***************************************************************************
Desc: This routine outputs the content of a DOM node in the Element
*****************************************************************************/
FSTATIC FLMBOOL OutputDomNode(
FLMUINT uiCol,
FLMUINT * puiRow,
eColorType uiBackColor,
eColorType uiForeColor,
FLMBYTE * pucVal,
STATE_INFO * pStateInfo)
{
RCODE rc = NE_XFLM_OK;
FLMBOOL bOk = FALSE;
FLMUINT uiLabelWidth = 30;
FLMUINT uiRow = *puiRow;
FLMUINT uiNumBytes;
FLMBYTE * pucData = pucVal;
FLMUINT uiDataOffset = pStateInfo->uiElmDataOffset;
FLMBYTE ucFlags = 0;
FLMBYTE ucExtFlags = 0;
FLMUINT uiSENLength = 0;
const FLMBYTE * pucTmp;
FLMUINT64 ui64Value;
FLMUINT uiValue;
// VISIT: change to use flmReadNodeInfo
if ((uiNumBytes = pStateInfo->uiElmDataLen) == 0)
{
bOk = TRUE;
goto Exit;
}
// Display the Node Type. The first byte is encoded as RDDDNNNN
// where R = Reserved, DDD = Data Type, NNNN = Node Type
// Display the Data Type
if (!ViewAddMenuItem( LBL_DOM_DATA_TYPE, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
(*pucData & 0x70) >> 4, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_DISABLED,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Display the Node Type
if (!ViewAddMenuItem( LBL_DOM_NODE_TYPE, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
*pucData & 0x0F, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_DISABLED,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
pucData++;
uiDataOffset++;
uiNumBytes--;
if (!uiNumBytes)
{
if (!ViewAddMenuItem( LBL_DOM_FLAGS, uiLabelWidth,
VAL_IS_LABEL_INDEX,
LBL_NO_VALUE, 0,
0, VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
ucFlags = *pucData;
// Display the flags
if (!ViewAddMenuItem( LBL_DOM_FLAGS, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
*pucData, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_DISABLED,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
pucData++;
uiDataOffset++;
uiNumBytes--;
}
// Name ID
if (!uiNumBytes)
{
if (!ViewAddMenuItem( LBL_DOM_NAME_ID, uiLabelWidth,
VAL_IS_LABEL_INDEX,
LBL_NO_VALUE, 0,
0, VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
pucTmp = pucData;
uiSENLength = f_getSENLength( *pucTmp);
if (uiNumBytes >= uiSENLength)
{
if( RC_BAD( rc = f_decodeSEN( &pucTmp,
&pucTmp[ FLM_MAX_NUM_BUF_SIZE], &uiValue)))
{
goto Exit;
}
if (!ViewAddMenuItem( LBL_DOM_NAME_ID, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
uiValue, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_SEN5 | MOD_HEX,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// If we can't display the number, at least display what we have left.
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DOM_NAME_ID,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
pucData, uiNumBytes, FALSE))
{
goto Exit;
}
uiSENLength = uiNumBytes;
}
pucData += uiSENLength;
uiNumBytes -= uiSENLength;
uiDataOffset += uiSENLength;
}
// Prefix ID
if (ucFlags & NSF_EXT_HAVE_PREFIX_BIT)
{
if (!uiNumBytes)
{
if (!ViewAddMenuItem( LBL_DOM_PREFIX_ID, uiLabelWidth,
VAL_IS_LABEL_INDEX,
LBL_NO_VALUE, 0,
0, VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
pucTmp = pucData;
uiSENLength = f_getSENLength( *pucTmp);
if (uiNumBytes >= uiSENLength)
{
if( RC_BAD( rc = f_decodeSEN( &pucTmp,
&pucTmp[ FLM_MAX_NUM_BUF_SIZE], &uiValue)))
{
goto Exit;
}
if (!ViewAddMenuItem( LBL_DOM_PREFIX_ID, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
uiValue, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_SEN5 | MOD_HEX,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// If we can't display the number, at least display what we have left.
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DOM_PREFIX_ID,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) +
uiDataOffset,
pucData, uiNumBytes, FALSE))
{
goto Exit;
}
uiSENLength = uiNumBytes;
}
pucData += uiSENLength;
uiNumBytes -= uiSENLength;
uiDataOffset += uiSENLength;
}
}
if (!uiNumBytes)
{
if (!ViewAddMenuItem( LBL_DOM_BASE_ID, uiLabelWidth,
VAL_IS_LABEL_INDEX,
LBL_NO_VALUE, 0,
0, VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// Base ID (required)
pucTmp = pucData;
uiSENLength = f_getSENLength( *pucTmp);
if (uiNumBytes >= uiSENLength)
{
if( RC_BAD( rc = f_decodeSEN64( &pucTmp,
&pucTmp[ FLM_MAX_NUM_BUF_SIZE], &ui64Value)))
{
goto Exit;
}
if (!ViewAddMenuItem( LBL_DOM_BASE_ID, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
ui64Value, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_SEN9 | MOD_HEX,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// If we can't display the number, at least display what we have left.
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DOM_BASE_ID,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
pucData, uiNumBytes, FALSE))
{
goto Exit;
}
uiSENLength = uiNumBytes;
}
pucData += uiSENLength;
uiDataOffset += uiSENLength;
uiNumBytes -= uiSENLength;
}
if (!uiNumBytes)
{
if (!ViewAddMenuItem( LBL_DOM_ROOT_ID, uiLabelWidth,
VAL_IS_LABEL_INDEX,
LBL_NO_VALUE, 0,
0, VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
pucTmp = pucData;
uiSENLength = f_getSENLength( *pucTmp);
if (uiNumBytes >= uiSENLength)
{
if( RC_BAD( rc = f_decodeSEN64( &pucTmp,
&pucTmp[ FLM_MAX_NUM_BUF_SIZE], &ui64Value)))
{
goto Exit;
}
if (!ViewAddMenuItem( LBL_DOM_ROOT_ID, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
ui64Value, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_SEN9 | MOD_HEX,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// If we can't display the number, at least display what we have left.
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DOM_ROOT_ID,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
pucData, uiNumBytes, FALSE))
{
goto Exit;
}
uiSENLength = uiNumBytes;
}
pucData += uiSENLength;
uiDataOffset += uiSENLength;
uiNumBytes -= uiSENLength;
}
if (!uiNumBytes)
{
if (!ViewAddMenuItem( LBL_DOM_PARENT_ID, uiLabelWidth,
VAL_IS_LABEL_INDEX,
LBL_NO_VALUE, 0,
0, VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
pucTmp = pucData;
uiSENLength = f_getSENLength( *pucTmp);
if (uiNumBytes >= uiSENLength)
{
if( RC_BAD( rc = f_decodeSEN64( &pucTmp,
&pucTmp[ FLM_MAX_NUM_BUF_SIZE], &ui64Value)))
{
goto Exit;
}
if (!ViewAddMenuItem( LBL_DOM_PARENT_ID, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
ui64Value, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_SEN9 | MOD_HEX,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// If we can't display the number, at least display what we have left.
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DOM_PARENT_ID,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
pucData, uiNumBytes, FALSE))
{
goto Exit;
}
uiSENLength = uiNumBytes;
}
pucData += uiSENLength;
uiDataOffset += uiSENLength;
uiNumBytes -= uiSENLength;
}
// Prev+Next Siblings
if (ucFlags & NSF_HAVE_SIBLINGS_BIT)
{
if (!uiNumBytes)
{
if (!ViewAddMenuItem( LBL_DOM_PREV_SIB_ID, uiLabelWidth,
VAL_IS_LABEL_INDEX,
LBL_NO_VALUE, 0,
0, VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// Previous
pucTmp = pucData;
uiSENLength = f_getSENLength( *pucTmp);
if (uiNumBytes >= uiSENLength)
{
if( RC_BAD( rc = f_decodeSEN64( &pucTmp,
&pucTmp[ FLM_MAX_NUM_BUF_SIZE], &ui64Value)))
{
goto Exit;
}
if (!ViewAddMenuItem( LBL_DOM_PREV_SIB_ID, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
ui64Value, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_SEN9 | MOD_HEX,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// If we can't display the number, at least display what we have left.
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DOM_PREV_SIB_ID,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
pucData, uiNumBytes, FALSE))
{
goto Exit;
}
uiSENLength = uiNumBytes;
}
pucData += uiSENLength;
uiDataOffset += uiSENLength;
uiNumBytes -= uiSENLength;
}
if (!uiNumBytes)
{
if (!ViewAddMenuItem( LBL_DOM_NEXT_SIB_ID, uiLabelWidth,
VAL_IS_LABEL_INDEX,
LBL_NO_VALUE, 0,
0, VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// Next
pucTmp = pucData;
uiSENLength = f_getSENLength( *pucTmp);
if (uiNumBytes >= uiSENLength)
{
if( RC_BAD( rc = f_decodeSEN64( &pucTmp,
&pucTmp[ FLM_MAX_NUM_BUF_SIZE], &ui64Value)))
{
goto Exit;
}
if (!ViewAddMenuItem( LBL_DOM_NEXT_SIB_ID, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
ui64Value, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_SEN9 | MOD_HEX,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// If we can't display the number, at least display what we have left.
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DOM_NEXT_SIB_ID,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
pucData, uiNumBytes, FALSE))
{
goto Exit;
}
uiSENLength = uiNumBytes;
}
pucData += uiSENLength;
uiDataOffset += uiSENLength;
uiNumBytes -= uiSENLength;
}
}
// First+Last Child ID
if (ucFlags & NSF_HAVE_CHILDREN_BIT)
{
// First
if (!uiNumBytes)
{
if (!ViewAddMenuItem( LBL_DOM_FIRST_CHILD_ID, uiLabelWidth,
VAL_IS_LABEL_INDEX,
LBL_NO_VALUE, 0,
0, VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
pucTmp = pucData;
uiSENLength = f_getSENLength( *pucTmp);
if (uiNumBytes >= uiSENLength)
{
if( RC_BAD( rc = f_decodeSEN64( &pucTmp,
&pucTmp[ FLM_MAX_NUM_BUF_SIZE], &ui64Value)))
{
goto Exit;
}
if (!ViewAddMenuItem( LBL_DOM_FIRST_CHILD_ID, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
ui64Value, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_SEN9 | MOD_HEX,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// If we can't display the number, at least display what we have left.
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DOM_FIRST_CHILD_ID,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
pucData, uiNumBytes, FALSE))
{
goto Exit;
}
uiSENLength = uiNumBytes;
}
pucData += uiSENLength;
uiDataOffset += uiSENLength;
uiNumBytes -= uiSENLength;
}
// Last
if (!uiNumBytes)
{
if (!ViewAddMenuItem( LBL_DOM_LAST_CHILD_ID, uiLabelWidth,
VAL_IS_LABEL_INDEX,
LBL_NO_VALUE, 0,
0, VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
pucTmp = pucData;
uiSENLength = f_getSENLength( *pucTmp);
if (uiNumBytes >= uiSENLength)
{
if( RC_BAD( rc = f_decodeSEN64( &pucTmp,
&pucTmp[ FLM_MAX_NUM_BUF_SIZE], &ui64Value)))
{
goto Exit;
}
if (!ViewAddMenuItem( LBL_DOM_LAST_CHILD_ID, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
ui64Value, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_SEN9 | MOD_HEX,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// If we can't display the number, at least display what we have left.
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DOM_LAST_CHILD_ID,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
pucData, uiNumBytes, FALSE))
{
goto Exit;
}
uiSENLength = uiNumBytes;
}
pucData += uiSENLength;
uiDataOffset += uiSENLength;
uiNumBytes -= uiSENLength;
}
}
// Annotation
if (ucExtFlags & NSF_EXT_ANNOTATION_BIT)
{
if (!uiNumBytes)
{
if (!ViewAddMenuItem( LBL_DOM_ANNOTATION_ID, uiLabelWidth,
VAL_IS_LABEL_INDEX,
LBL_NO_VALUE, 0,
0, VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
pucTmp = pucData;
uiSENLength = f_getSENLength( *pucTmp);
if (uiNumBytes >= uiSENLength)
{
if( RC_BAD( rc = f_decodeSEN64( &pucTmp,
&pucTmp[ FLM_MAX_NUM_BUF_SIZE], &ui64Value)))
{
goto Exit;
}
if (!ViewAddMenuItem( LBL_DOM_ANNOTATION_ID, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
ui64Value, 0,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
0, MOD_SEN9 | MOD_HEX,
uiCol, uiRow++, 0,
uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
else
{
// If we can't display the number, at least display what we have left.
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DOM_ANNOTATION_ID,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) + uiDataOffset,
pucData, uiNumBytes, FALSE))
{
goto Exit;
}
uiSENLength = uiNumBytes;
}
pucData += uiSENLength;
uiDataOffset += uiSENLength;
uiNumBytes -= uiSENLength;
}
}
if (uiNumBytes)
{
// Output whatever is left as a HEX dump.
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DOM_VALUE,
FSGetFileNumber( pStateInfo->ui32BlkAddress),
FSGetFileOffset( pStateInfo->ui32BlkAddress) +
uiDataOffset,
pucData, uiNumBytes, FALSE))
{
goto Exit;
}
}
bOk = TRUE;
Exit:
*puiRow = uiRow;
return( bOk);
}
/***************************************************************************
Desc: This routine outputs the elements in a LEAF block.
*****************************************************************************/
FSTATIC FLMBOOL OutputLeafElements(
FLMUINT uiCol,
FLMUINT * puiRow,
F_BTREE_BLK_HDR * pBlkHdr,
BLK_EXP_p pBlkExp,
FLMBYTE * pucBlkStatus,
FLMBOOL bStatusOnlyFlag
)
{
// VISIT: There are a number of places throughout that have been commentd out
// that have to do with the block status. Currently, the pucBlkStatus
// flag is not being updated in a meaningful way. Need to investigate
// what this is used for and find a way to make it meaningful.
FLMBOOL bOk = FALSE;
FLMUINT uiLabelWidth = 30;
eColorType uiBackColor = FLM_BLACK;
eColorType uiForeColor = FLM_LIGHTGRAY;
eColorType uiUnselectBackColor = FLM_BLACK;
eColorType uiUnselectForeColor = FLM_WHITE;
eColorType uiSelectBackColor = FLM_BLUE;
eColorType uiSelectForeColor = FLM_WHITE;
FLMUINT uiRow = *puiRow;
FLMUINT uiElementCount = 0;
FLMINT iErrorCode;
// LFileType eLfType = LF_INVALID;
FLMBYTE ucElmStatus [NUM_STATUS_BYTES];
STATE_INFO StateInfo;
// LF_HDR_p pLogicalFile = NULL;
FLMUINT uiCurOffset;
FLMUINT16 * pui16OffsetArray;
FLMUINT uiOption;
FLMBOOL bHasData = (pBlkHdr->stdBlkHdr.ui8BlkType == BT_LEAF_DATA);
if (pBlkExp->uiLfNum == 0)
{
pBlkExp->uiLfNum = (FLMUINT)pBlkHdr->ui16LogicalFile;
}
// Setup the STATE variable for processing through the block
(void)ViewGetDictInfo();
#if 0
if ((iErrorCode = flmVerifyBlockHeader( &StateInfo,
&BlockInfo,
(FLMUINT)gv_ViewDbHdr.ui16BlockSize,
pBlkExp->uiNextAddr,
pBlkExp->uiPrevAddr,
(FLMBOOL)(StateInfo.pDb != NULL
? TRUE
: FALSE))) != 0)
{
SetStatusBit( pucBlkStatus, iErrorCode);
}
#endif
uiCurOffset = 0;
pui16OffsetArray = (FLMUINT16 *)((FLMBYTE *)pBlkHdr + sizeofBTreeBlkHdr( pBlkHdr));
// Read through the elements in the block
while( uiCurOffset <= (FLMUINT)(pBlkHdr->ui16NumKeys - 1))
{
InitStatusBits( ucElmStatus);
uiElementCount++;
GetElmInfo( (FLMBYTE *)pBlkHdr + pui16OffsetArray[ uiCurOffset], pBlkHdr, &StateInfo);
iErrorCode = 0; // ??
#if 0
if ((iErrorCode = flmVerifyElement( &StateInfo,
FO_DO_EXTENDED_DATA_CHECK)) != 0)
{
SetStatusBit( ucElmStatus, iErrorCode);
}
else if (eLfType == XFLM_LF_INDEX)
{
if (StateInfo.uiCurKeyLen)
{
if (RC_BAD( flmVerifyIXRefs( &StateInfo, NULL, 0,
&iErrorCode)) || iErrorCode != 0)
{
SetStatusBit( ucElmStatus, iErrorCode);
}
}
}
#endif
// Output the element
if (!bStatusOnlyFlag)
{
uiRow++;
// Output the element number
if (!ViewAddMenuItem( LBL_ELEMENT_NUMBER, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)uiElementCount, 0,
0,
VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0,
FLM_GREEN, FLM_WHITE,
FLM_GREEN, FLM_WHITE))
{
goto Exit;
}
// Remember this item if we are searching
#if 0
if ((gv_bViewSearching) &&
(flmCompareKeys( StateInfo.pucCurKey, StateInfo.uiCurKeyLen,
gv_ucViewSearchKey,
gv_uiViewSearchKeyLen) >= 0) &&
(gv_pViewSearchItem == NULL))
{
gv_pViewSearchItem = gv_pViewMenuLastItem;
}
#endif
// Output the element offset within the block
if (!ViewAddMenuItem( LBL_ELEMENT_OFFSET, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)StateInfo.uiElmOffset, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) + StateInfo.uiElmOffset,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output the element length
if (!ViewAddMenuItem( LBL_ELEMENT_LENGTH, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)StateInfo.uiElmLen, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) + StateInfo.uiElmOffset,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Display the first element flag if present
if (bHasData)
{
if (!ViewAddMenuItem( LBL_FIRST_ELEMENT_FLAG, uiLabelWidth,
VAL_IS_LABEL_INDEX,
(bteFirstElementFlag( StateInfo.pucElm)
? (FLMUINT64)LBL_YES
: (FLMUINT64)LBL_NO), 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) + StateInfo.uiElmOffset,
0x80, MOD_BITS | MOD_DECIMAL,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Display the last element flag
if (!ViewAddMenuItem( LBL_LAST_ELEMENT_FLAG, uiLabelWidth,
VAL_IS_LABEL_INDEX,
(bteLastElementFlag( StateInfo.pucElm)
? (FLMUINT64)LBL_YES
: (FLMUINT64)LBL_NO), 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) + StateInfo.uiElmOffset,
0x40, MOD_BITS | MOD_DECIMAL,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Display the Data Only flag
if (!ViewAddMenuItem( LBL_DATA_BLOCK_FLAG, uiLabelWidth,
VAL_IS_LABEL_INDEX,
(bteDataBlockFlag( StateInfo.pucElm)
? (FLMUINT64)LBL_YES
: (FLMUINT64)LBL_NO), 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) + StateInfo.uiElmOffset,
0x40, MOD_BITS | MOD_DECIMAL,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
// Display the key length
if (!ViewAddMenuItem( LBL_KEY_LENGTH, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)StateInfo.uiElmKeyLen, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmKeyLenOffset,
0, MOD_DECIMAL,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output the current key portion, if any
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_ELEMENT_KEY,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmKeyOffset,
StateInfo.pucElmKey, StateInfo.uiElmKeyLen,
FALSE))
{
goto Exit;
}
// Display the data length
if (bHasData)
{
// Output the overall data field (if present)
if (bteOADataLenFlag( StateInfo.pucElm))
{
if (!ViewAddMenuItem( LBL_OA_DATA_LENGTH, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)StateInfo.uiElmOADataLen, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmOADataLenOffset,
0, MOD_FLMBYTE | MOD_DECIMAL,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
if (!ViewAddMenuItem( LBL_DATA_LENGTH, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)StateInfo.uiElmDataLen, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmDataLenOffset,
0, MOD_FLMBYTE | MOD_DECIMAL,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output the data portion
// Check for a data only block.
if ( bteDataBlockFlag( StateInfo.pucElm))
{
FLMUINT uiTempAddress = FB2UD( StateInfo.pucElmData);
if (uiTempAddress == 0)
{
uiOption = 0;
}
else
{
uiOption = BLK_OPTION_DATA_BLOCK | StateInfo.uiElmOffset;
}
if (!ViewAddMenuItem( LBL_DATA_BLOCK_ADDRESS, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
(FLMUINT64)uiTempAddress, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmDataOffset,
0, MOD_DISABLED, uiCol, uiRow++, uiOption,
(!uiOption ? uiBackColor : uiUnselectBackColor),
(!uiOption ? uiForeColor : uiUnselectForeColor),
(!uiOption ? uiBackColor : uiSelectBackColor),
(!uiOption ? uiForeColor : uiSelectForeColor)))
{
goto Exit;
}
}
else
{
if ( bteFirstElementFlag( StateInfo.pucElm) &&
!isIndexBlk((F_BTREE_BLK_HDR *)StateInfo.pBlkHdr))
{
if (!OutputDomNode( uiCol, &uiRow,
uiBackColor, uiForeColor,
StateInfo.pucElmData + 1, &StateInfo))
{
goto Exit;
}
}
else
{
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DATA,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmDataOffset,
StateInfo.pucElmData, StateInfo.uiElmDataLen,
FALSE))
{
goto Exit;
}
}
}
}
}
// Go to the next element
uiCurOffset++;
OrStatusBits( pucBlkStatus, ucElmStatus);
}
if (!bStatusOnlyFlag)
{
*puiRow = uiRow;
// If we were searching and did not find a key, set it on the
// last key found
if (gv_bViewSearching && !gv_pViewSearchItem)
{
gv_pViewSearchItem = gv_pViewMenuLastItem;
while (gv_pViewSearchItem &&
gv_pViewSearchItem->iLabelIndex != LBL_ELEMENT_NUMBER)
{
gv_pViewSearchItem = gv_pViewSearchItem->pPrevItem;
}
}
}
bOk = TRUE;
Exit:
*puiRow = uiRow;
#if 0
if (bStateInitialized && StateInfo.pRecord)
{
StateInfo.pRecord->release( &StateInfo.pRecord);
}
#endif
return( bOk);
}
/***************************************************************************
Desc: This routine outputs the elements in a DATA-ONLY block.
*****************************************************************************/
FSTATIC FLMBOOL OutputDataOnlyElements(
FLMUINT uiCol,
FLMUINT * puiRow,
F_BLK_HDR * pBlkHdr,
BLK_EXP_p, //pBlkExp,
FLMBYTE *, //pucBlkStatus,
FLMBOOL bStatusOnlyFlag
)
{
FLMBOOL bOk = FALSE;
FLMUINT uiLabelWidth = 30;
eColorType uiBackColor = FLM_BLACK;
eColorType uiForeColor = FLM_LIGHTGRAY;
FLMUINT uiRow = *puiRow;
FLMINT iErrorCode;
// LFileType eLfType = LF_INVALID;
FLMBYTE ucElmStatus [NUM_STATUS_BYTES];
STATE_INFO StateInfo;
// Setup the STATE variable for processing through the block
(void)ViewGetDictInfo();
#if 0
if ((iErrorCode = flmVerifyBlockHeader( &StateInfo, &BlockInfo,
(FLMUINT)gv_ViewDbHdr.ui16BlockSize,
pBlkExp->uiNextAddr,
pBlkExp->uiPrevAddr,
(FLMBOOL)(StateInfo.pDb != NULL
? TRUE
: FALSE))) != 0)
{
SetStatusBit( pucBlkStatus, iErrorCode);
}
#endif
// Read through the block
InitStatusBits( ucElmStatus);
GetElmInfo( (FLMBYTE *)pBlkHdr + SIZEOF_STD_BLK_HDR,
(F_BTREE_BLK_HDR *)pBlkHdr, &StateInfo);
iErrorCode = 0; // ??
#if 0
if ((iErrorCode = flmVerifyElement( &StateInfo,
FO_DO_EXTENDED_DATA_CHECK)) != 0)
{
SetStatusBit( ucElmStatus, iErrorCode);
}
else if (eLfType == XFLM_LF_INDEX)
{
if (StateInfo.uiCurKeyLen)
{
if (RC_BAD( flmVerifyIXRefs( &StateInfo, NULL, 0,
&iErrorCode)) || iErrorCode != 0)
{
SetStatusBit( ucElmStatus, iErrorCode);
}
}
}
#endif
// Output the element
if (!bStatusOnlyFlag)
{
uiRow++;
// Remember this item if we are searching
#if 0
if ((gv_bViewSearching) &&
(flmCompareKeys( StateInfo.pucCurKey, StateInfo.uiCurKeyLen,
gv_ucViewSearchKey,
gv_uiViewSearchKeyLen) >= 0) &&
(gv_pViewSearchItem == NULL))
{
gv_pViewSearchItem = gv_pViewMenuLastItem;
}
#endif
// Output the element length
if (!ViewAddMenuItem( LBL_ELEMENT_LENGTH, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)StateInfo.uiElmLen, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmOffset,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Display the key length if there is a key...
if ( StateInfo.uiElmKeyLen)
{
if (!ViewAddMenuItem( LBL_KEY_LENGTH, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)StateInfo.uiElmKeyLen, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmKeyOffset, 0,
MOD_DECIMAL,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output the key portion
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_ELEMENT_KEY,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmKeyOffset,
StateInfo.pucElmKey, StateInfo.uiElmKeyLen,
FALSE))
{
goto Exit;
}
}
// Display the data length
if (!ViewAddMenuItem( LBL_DATA_LENGTH, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)StateInfo.uiElmDataLen, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmDataLenOffset,
0,
MOD_FLMBYTE | MOD_DECIMAL,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output the data portion.
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_DATA,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmDataOffset,
StateInfo.pucElmData, StateInfo.uiElmDataLen,
FALSE))
{
goto Exit;
}
}
if (!bStatusOnlyFlag)
{
*puiRow = uiRow;
// If we were searching and did not find a key, set it on the
// last key found
if (gv_bViewSearching && !gv_pViewSearchItem)
{
gv_pViewSearchItem = gv_pViewMenuLastItem;
while (gv_pViewSearchItem &&
gv_pViewSearchItem->iLabelIndex != LBL_ELEMENT_NUMBER)
{
gv_pViewSearchItem = gv_pViewSearchItem->pPrevItem;
}
}
}
bOk = TRUE;
Exit:
return( bOk);
}
/***************************************************************************
Desc: This routine outputs a LEAF block, including the block header.
*****************************************************************************/
FLMBOOL ViewLeafBlk(
FLMUINT uiReadAddress,
FLMUINT uiBlkAddress,
F_BLK_HDR ** ppBlkHdr,
BLK_EXP_p pBlkExp
)
{
FLMBOOL bOk = FALSE;
FLMUINT uiRow;
FLMUINT uiCol;
F_BLK_HDR * pBlkHdr;
FLMBYTE ucBlkStatus [NUM_STATUS_BYTES];
FLMUINT32 ui32CalcCRC;
FLMUINT32 ui32BlkCRC;
FLMUINT uiBytesRead;
InitStatusBits( ucBlkStatus);
// Read the block into memory
if (!ViewBlkRead( uiReadAddress, ppBlkHdr, TRUE,
(FLMUINT)gv_ViewDbHdr.ui16BlockSize,
&ui32CalcCRC, &ui32BlkCRC,
&uiBytesRead, TRUE))
{
goto Exit;
}
pBlkHdr = *ppBlkHdr;
ViewMenuInit( "LEAF Block");
// Output the block header first
uiRow = 0;
uiCol = 5;
pBlkExp->uiType = pBlkHdr->ui8BlkType;
pBlkExp->uiBlkAddr = uiBlkAddress;
pBlkExp->uiLevel = 0;
OutputLeafElements( uiCol, &uiRow, (F_BTREE_BLK_HDR *)pBlkHdr,
pBlkExp, ucBlkStatus, TRUE);
if (!ViewOutBlkHdr( uiCol, &uiRow, pBlkHdr, pBlkExp, ucBlkStatus,
ui32CalcCRC, ui32BlkCRC))
{
goto Exit;
}
// Now output the leaf data
if (!OutputLeafElements( uiCol, &uiRow, (F_BTREE_BLK_HDR *)pBlkHdr,
pBlkExp, ucBlkStatus, FALSE))
{
goto Exit;
}
bOk = TRUE;
Exit:
return( bOk);
}
/***************************************************************************
Desc: This routine outputs a Data Only block, including the block header.
*****************************************************************************/
FLMBOOL ViewDataBlk(
FLMUINT uiReadAddress,
FLMUINT uiBlkAddress,
F_BLK_HDR ** ppBlkHdr,
BLK_EXP_p pBlkExp
)
{
FLMBOOL bOk = FALSE;
FLMUINT uiRow;
FLMUINT uiCol;
F_BLK_HDR * pBlkHdr;
FLMBYTE ucBlkStatus [NUM_STATUS_BYTES];
FLMUINT32 ui32CalcCRC;
FLMUINT32 ui32BlkCRC;
FLMUINT uiBytesRead;
InitStatusBits( ucBlkStatus);
// Read the block into memory
if (!ViewBlkRead( uiReadAddress, ppBlkHdr, TRUE,
(FLMUINT)gv_ViewDbHdr.ui16BlockSize,
&ui32CalcCRC, &ui32BlkCRC,
&uiBytesRead, TRUE))
{
goto Exit;
}
pBlkHdr = *ppBlkHdr;
ViewMenuInit( "DATA Block");
// Output the block header first
uiRow = 0;
uiCol = 5;
pBlkExp->uiType = pBlkHdr->ui8BlkType;
pBlkExp->uiBlkAddr = uiBlkAddress;
pBlkExp->uiLevel = 0;
OutputDataOnlyElements( uiCol, &uiRow, pBlkHdr,
pBlkExp, ucBlkStatus, TRUE);
if (!ViewOutBlkHdr( uiCol, &uiRow, pBlkHdr, pBlkExp, ucBlkStatus,
ui32CalcCRC, ui32BlkCRC))
{
goto Exit;
}
// Now output the leaf data
if (!OutputDataOnlyElements( uiCol, &uiRow, pBlkHdr,
pBlkExp, ucBlkStatus, FALSE))
{
goto Exit;
}
bOk = TRUE;
Exit:
return( bOk);
}
/***************************************************************************
Desc: This routine outputs the elements of a NON-LEAF block.
*****************************************************************************/
FSTATIC FLMBOOL OutputNonLeafElements(
FLMUINT uiCol,
FLMUINT * puiRow,
F_BTREE_BLK_HDR * pBlkHdr,
BLK_EXP_p pBlkExp,
FLMBYTE * pucBlkStatus,
FLMBOOL bStatusOnlyFlag
)
{
FLMBOOL bOk = FALSE;
FLMUINT uiLabelWidth = 30;
eColorType uiBackColor = FLM_BLACK;
eColorType uiForeColor = FLM_LIGHTGRAY;
eColorType uiUnselectBackColor = FLM_BLACK;
eColorType uiUnselectForeColor = FLM_WHITE;
eColorType uiSelectBackColor = FLM_BLUE;
eColorType uiSelectForeColor = FLM_WHITE;
FLMUINT uiRow = *puiRow;
FLMUINT uiElementCount = 0;
// FLMBYTE * pucTmpAddr;
FLMUINT uiTempAddress;
FLMUINT iErrorCode=0;
FLMUINT uiOption;
eLFileType eLfType;
FLMUINT uiBlkType = (FLMUINT)pBlkHdr->stdBlkHdr.ui8BlkType;
FLMBYTE ucElmStatus [NUM_STATUS_BYTES];
STATE_INFO StateInfo;
// FLMBOOL bStateInitialized = FALSE;
// BLOCK_INFO BlockInfo;
// FLMBYTE ucKeyBuffer [MAX_KEY_SIZ];
// LF_HDR LogicalFile;
LF_HDR * pLogicalFile = NULL;
// LFILE_p pLFile = NULL;
// FLMUINT uiFixedDrn;
FLMUINT16 * pui16OffsetArray;
FLMUINT uiCurOffset;
if (pBlkExp->uiLfNum == 0)
{
pBlkExp->uiLfNum = (FLMUINT)pBlkHdr->ui16LogicalFile;
}
pui16OffsetArray = (FLMUINT16 *)((FLMBYTE *)pBlkHdr + sizeofBTreeBlkHdr( pBlkHdr));
uiCurOffset = 0;
// Setup the STATE variable for processing through the block
(void)ViewGetDictInfo();
#if 0
if (gv_bViewHaveDictInfo)
{
F_Dict * pDict = gv_hViewDb->pDict;
if (isContainerBlk( pBlkHdr))
{
if (RC_OK( pDict->getContainer( pBlkExp->uiLfNum, &pLFile)))
{
f_memset( &LogicalFile, 0, sizeof( LF_HDR));
pLogicalFile = &LogicalFile;
LogicalFile.pLFile = pLFile;
}
}
else
{
IXD * pIxd;
if (RC_OK( pDict->getIndex( pBlkExp->uiLfNum, &pLFile, &pIxd)))
{
f_memset( &LogicalFile, 0, sizeof( LF_HDR));
pLogicalFile = &LogicalFile;
LogicalFile.pLFile = pLFile;
LogicalFile.pIxd = pIxd;
LogicalFile.pIfd = pIxd->pFirstIfd;
}
}
}
#endif
eLfType = (pLogicalFile) ? pLogicalFile->eLfType : XFLM_LF_INVALID;
#if 0
flmInitReadState( &StateInfo, &bStateInitialized,
(FLMUINT)gv_ViewDbHdr.ui32DbVersion,
(gv_bViewDbInitialized)
? gv_hViewDb
: NULL,
pLogicalFile, pBlkExp->uiLevel,
uiBlkType, ucKeyBuffer);
if ((iErrorCode = flmVerifyBlockHeader( &StateInfo, &BlockInfo,
(FLMUINT)gv_ViewDbHdr.ui16BlockSize,
pBlkExp->uiNextAddr,
pBlkExp->uiPrevAddr,
(FLMBOOL)(StateInfo.pDb != NULL
? TRUE
: FALSE))) != 0)
{
SetStatusBit( pucBlkStatus, iErrorCode);
}
#endif
// Output each element in the block
while (uiCurOffset <= (FLMUINT)(pBlkHdr->ui16NumKeys - 1))
{
InitStatusBits( ucElmStatus);
uiElementCount++;
GetElmInfo( (FLMBYTE *)pBlkHdr +
pui16OffsetArray[ uiCurOffset],
pBlkHdr, &StateInfo);
/*
if ((iErrorCode = flmVerifyElement( &StateInfo,
FO_DO_EXTENDED_DATA_CHECK)) != 0)
{
SetStatusBit( ucElmStatus, iErrorCode);
}
*/
if (!bStatusOnlyFlag)
{
uiRow++;
// Output the element number
if (!ViewAddMenuItem( LBL_ELEMENT_NUMBER, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)uiElementCount, 0,
0,
VIEW_INVALID_FILE_OFFSET,
0, MOD_DISABLED,
uiCol, uiRow++, 0,
FLM_GREEN, FLM_WHITE,
FLM_GREEN, FLM_WHITE))
{
goto Exit;
}
// Output the element offset within the block
if (!ViewAddMenuItem( LBL_ELEMENT_OFFSET, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)StateInfo.uiElmOffset, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmOffset,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output the element length
if (!ViewAddMenuItem( LBL_ELEMENT_LENGTH, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)StateInfo.uiElmLen, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmOffset,
0, MOD_DISABLED,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Display the child block address
uiTempAddress = FB2UD( StateInfo.pucElm);
if (uiTempAddress == 0)
{
uiOption = 0;
}
else
{
uiOption = BLK_OPTION_CHILD_BLOCK | StateInfo.uiElmOffset;
}
if (!ViewAddMenuItem( LBL_CHILD_BLOCK_ADDRESS, uiLabelWidth,
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
(FLMUINT64)uiTempAddress, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmOffset,
0, MOD_CHILD_BLK, uiCol, uiRow++, uiOption,
(!uiOption ? uiBackColor : uiUnselectBackColor),
(!uiOption ? uiForeColor : uiUnselectForeColor),
(!uiOption ? uiBackColor : uiSelectBackColor),
(!uiOption ? uiForeColor : uiSelectForeColor)))
{
goto Exit;
}
// Display the counts info if any.
if (uiBlkType == BT_NON_LEAF_COUNTS)
{
if (!ViewAddMenuItem( LBL_CHILD_REFERENCE_COUNT, uiLabelWidth,
VAL_IS_NUMBER,
(FLMUINT64) StateInfo.uiElmCounts, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmCountsOffset,
0, MOD_FLMUINT32 | MOD_DECIMAL,
uiCol, uiRow++, uiOption, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
}
// Remember this item if we are searching
#if 0
if (gv_bViewSearching &&
flmCompareKeys( StateInfo.pucCurKey, StateInfo.uiCurKeyLen,
gv_ucViewSearchKey, gv_uiViewSearchKeyLen) >= 0 &&
!gv_pViewSearchItem)
{
gv_pViewSearchItem = gv_pViewMenuLastItem;
}
#endif
if (iErrorCode != 0)
{
if (!OutputStatus( uiCol, &uiRow, uiBackColor, uiForeColor,
uiLabelWidth, LBL_ELEMENT_STATUS, ucElmStatus))
{
goto Exit;
}
}
// Display the key length
if (!ViewAddMenuItem( LBL_KEY_LENGTH, uiLabelWidth,
VAL_IS_NUMBER | DISP_DECIMAL,
(FLMUINT64)StateInfo.uiElmKeyLen, 0,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmKeyLenOffset, 0,
MOD_DECIMAL,
uiCol, uiRow++, 0, uiBackColor, uiForeColor,
uiBackColor, uiForeColor))
{
goto Exit;
}
// Output the key
if (!OutputHexValue( uiCol, &uiRow,
uiBackColor, uiForeColor, LBL_ELEMENT_KEY,
FSGetFileNumber( StateInfo.ui32BlkAddress),
FSGetFileOffset( StateInfo.ui32BlkAddress) +
StateInfo.uiElmKeyOffset,
StateInfo.pucElmKey, StateInfo.uiElmKeyLen,
FALSE))
{
goto Exit;
}
}
// Go to the next element
uiCurOffset++;
OrStatusBits( pucBlkStatus, ucElmStatus);
}
if (!bStatusOnlyFlag)
{
*puiRow = uiRow;
// If we were searching and did not find a key, set it on the
// last key found
if (gv_bViewSearching && !gv_pViewSearchItem)
{
gv_pViewSearchItem = gv_pViewMenuLastItem;
while (gv_pViewSearchItem &&
gv_pViewSearchItem->iLabelIndex != LBL_CHILD_BLOCK_ADDRESS)
{
gv_pViewSearchItem = gv_pViewSearchItem->pPrevItem;
}
}
}
bOk = TRUE;
Exit:
#if 0
if (bStateInitialized && StateInfo.pRecord)
{
StateInfo.pRecord->release( &StateInfo.pRecord);
}
#endif
return( bOk);
}
/***************************************************************************
Desc: This routine outputs a NON-LEAF block, including the block header.
*****************************************************************************/
FLMBOOL ViewNonLeafBlk(
FLMUINT uiReadAddress,
FLMUINT uiBlkAddress,
F_BLK_HDR ** ppBlkHdr,
BLK_EXP_p pBlkExp
)
{
FLMBOOL bOk = FALSE;
FLMUINT uiRow;
FLMUINT uiCol;
F_BLK_HDR * pBlkHdr;
FLMBYTE ucBlkStatus [NUM_STATUS_BYTES];
FLMUINT32 ui32CalcCRC;
FLMUINT32 ui32BlkCRC;
FLMUINT uiBytesRead;
InitStatusBits( ucBlkStatus);
// Read the block into memory
if (!ViewBlkRead( uiReadAddress, ppBlkHdr, TRUE,
(FLMUINT)gv_ViewDbHdr.ui16BlockSize,
&ui32CalcCRC, &ui32BlkCRC,
&uiBytesRead, TRUE))
{
goto Exit;
}
pBlkHdr = *ppBlkHdr;
ViewMenuInit( "NON-LEAF Block");
// Output the block header first
uiRow = 0;
uiCol = 5;
pBlkExp->uiType = (FLMUINT)pBlkHdr->ui8BlkType;
pBlkExp->uiBlkAddr = uiBlkAddress;
OutputNonLeafElements( uiCol, &uiRow, (F_BTREE_BLK_HDR *)pBlkHdr,
pBlkExp, ucBlkStatus, TRUE);
if (!ViewOutBlkHdr( uiCol, &uiRow, pBlkHdr, pBlkExp, ucBlkStatus,
ui32CalcCRC, ui32BlkCRC))
{
goto Exit;
}
// Now output the non-leaf data
if (!OutputNonLeafElements( uiCol, &uiRow, (F_BTREE_BLK_HDR *)pBlkHdr,
pBlkExp, ucBlkStatus, FALSE))
{
goto Exit;
}
bOk = TRUE;
Exit:
return( bOk);
}
/********************************************************************
Desc: View a block in HEX
*********************************************************************/
void ViewHexBlock(
FLMUINT uiReadAddress,
F_BLK_HDR ** ppBlkHdr,
FLMUINT uiViewLen
)
{
FLMBYTE * pucBlk;
FLMUINT uiRow = 0;
FLMUINT uiCol = 13;
FLMUINT uiBytesPerLine = MAX_HORIZ_SIZE( uiCol);
FLMUINT uiBytesProcessed = 0;
FLMUINT uiNumBytes;
FLMUINT uiFileOffset;
FLMUINT uiFileNumber;
char szTitle [80];
FLMUINT uiBytesRead;
uiFileOffset = FSGetFileOffset( uiReadAddress);
uiFileNumber = FSGetFileNumber( uiReadAddress);
if (!ViewBlkRead( uiReadAddress, ppBlkHdr, uiViewLen, FALSE,
NULL, NULL, &uiBytesRead, TRUE))
{
return;
}
pucBlk = (FLMBYTE *)(*ppBlkHdr);
f_sprintf( szTitle, "HEX DISPLAY OF BLOCK %08X", (unsigned)uiReadAddress);
ViewMenuInit( szTitle);
while (uiBytesProcessed < uiViewLen)
{
if ((uiNumBytes = uiViewLen - uiBytesProcessed) > uiBytesPerLine)
{
uiNumBytes = uiBytesPerLine;
}
// Output the line
if (!ViewAddMenuItem( -1, 0,
VAL_IS_BINARY_HEX,
(FLMUINT)pucBlk, uiNumBytes,
uiFileNumber, uiFileOffset, uiNumBytes, MOD_BINARY,
uiCol, uiRow++, 0,
FLM_BLACK, FLM_LIGHTGRAY,
FLM_BLACK, FLM_LIGHTGRAY))
{
return;
}
uiFileOffset += uiNumBytes;
uiBytesProcessed += uiNumBytes;
pucBlk += uiNumBytes;
}
}
/***************************************************************************
Desc: This routine outputs a block in the database. Depending on the
type of block, it will call a different routine to display
the block. The routine then allows the user to press keys to
navigate to other blocks in the database if desired.
*****************************************************************************/
void ViewBlocks(
FLMUINT uiReadAddress,
FLMUINT uiBlkAddress,
BLK_EXP_p pBlkExp
)
{
FLMUINT uiOption;
VIEW_INFO SaveView;
VIEW_INFO DummySave;
FLMBOOL bRepaint = TRUE;
F_BLK_HDR * pBlkHdr = NULL;
FLMUINT uiBlkAddress2;
BLK_EXP BlkExp2;
FLMBOOL bSetExp = FALSE;
FLMBOOL bViewHexFlag = FALSE;
FLMUINT uiBytesRead;
// Loop getting commands until hit the exit key
if (!gv_bViewHdrRead)
{
ViewReadHdr();
}
gv_pViewSearchItem = NULL;
ViewReset( &SaveView);
while (!gv_bViewPoppingStack)
{
// Display the type of block expected
if (bRepaint)
{
if (bViewHexFlag)
{
ViewHexBlock( uiReadAddress, &pBlkHdr,
(FLMUINT)gv_ViewDbHdr.ui16BlockSize);
}
else
{
Switch_Statement:
switch (pBlkExp->uiType)
{
case BT_NON_LEAF_COUNTS:
case BT_NON_LEAF:
if (!ViewNonLeafBlk( uiReadAddress, uiBlkAddress,
&pBlkHdr, pBlkExp))
{
goto Exit;
}
break;
case BT_LEAF:
case BT_LEAF_DATA:
if (!ViewLeafBlk( uiReadAddress, uiBlkAddress,
&pBlkHdr, pBlkExp))
{
goto Exit;
}
break;
case BT_DATA_ONLY:
if (!ViewDataBlk( uiReadAddress, uiBlkAddress,
&pBlkHdr, pBlkExp))
{
goto Exit;
}
break;
case BT_FREE:
if (!ViewAvailBlk( uiReadAddress, uiBlkAddress,
&pBlkHdr, pBlkExp))
{
goto Exit;
}
break;
case BT_LFH_BLK:
if (!ViewLFHBlk( uiReadAddress, uiBlkAddress,
&pBlkHdr, pBlkExp))
{
goto Exit;
}
break;
case 0xFF:
if (!ViewBlkRead( uiReadAddress, &pBlkHdr, TRUE,
(FLMUINT)gv_ViewDbHdr.ui16BlockSize,
NULL, NULL, &uiBytesRead, FALSE))
{
goto Exit;
}
else
{
pBlkExp->uiType = (FLMUINT)pBlkHdr->ui8BlkType;
goto Switch_Statement;
}
}
}
}
// See what the user wants to do next.
if (bSetExp &&
(pBlkExp->uiType == BT_LEAF ||
pBlkExp->uiType == BT_NON_LEAF_COUNTS ||
pBlkExp->uiType == BT_NON_LEAF ||
pBlkExp->uiType == BT_LEAF_DATA))
{
pBlkExp->uiLfNum =
(FLMUINT)(((F_BTREE_BLK_HDR *)pBlkHdr)->ui16LogicalFile);
pBlkExp->uiLevel =
(FLMUINT)(((F_BTREE_BLK_HDR *)pBlkHdr)->ui8BlkLevel);
}
bSetExp = FALSE;
bRepaint = TRUE;
if (gv_bViewSearching)
{
SetSearchTopBottom();
if (pBlkExp->uiType == BT_LEAF ||
pBlkExp->uiType == BT_LEAF_DATA ||
!gv_pViewSearchItem)
{
gv_bViewSearching = FALSE;
ViewEnable();
uiOption = ViewGetMenuOption();
}
else
{
uiOption = gv_pViewSearchItem->uiOption;
}
}
else
{
ViewEnable();
uiOption = ViewGetMenuOption();
}
switch (uiOption)
{
case ESCAPE_OPTION:
goto Exit;
case PREV_BLOCK_OPTION:
ViewReset( &DummySave);
pBlkExp->uiNextAddr = uiBlkAddress;
pBlkExp->uiPrevAddr = 0xFFFFFFFF;
uiReadAddress = uiBlkAddress =
(FLMUINT)pBlkHdr->ui32PrevBlkInChain;
break;
case NEXT_BLOCK_OPTION:
ViewReset( &DummySave);
pBlkExp->uiNextAddr = 0xFFFFFFFF;
pBlkExp->uiPrevAddr = uiBlkAddress;
uiReadAddress = uiBlkAddress =
(FLMUINT)pBlkHdr->ui32NextBlkInChain;
break;
case PREV_BLOCK_IMAGE_OPTION:
f_memcpy( &BlkExp2, pBlkExp, sizeof( BLK_EXP));
BlkExp2.uiNextAddr = 0xFFFFFFFF;
BlkExp2.uiPrevAddr = 0xFFFFFFFF;
ViewBlocks( (FLMUINT)pBlkHdr->ui32PriorBlkImgAddr,
uiBlkAddress, &BlkExp2);
break;
case GOTO_BLOCK_OPTION:
if (GetBlockAddrType( &uiBlkAddress2))
{
ViewReset( &DummySave);
uiReadAddress = uiBlkAddress = uiBlkAddress2;
pBlkExp->uiType = 0xFF;
pBlkExp->uiLevel = 0xFF;
pBlkExp->uiNextAddr = 0xFFFFFFFF;
pBlkExp->uiPrevAddr = 0xFFFFFFFF;
pBlkExp->uiLfNum = 0;
bSetExp = TRUE;
if (uiBlkAddress < 2048)
{
bViewHexFlag = TRUE;
}
}
else
{
bRepaint = FALSE;
}
break;
case EDIT_OPTION:
case EDIT_RAW_OPTION:
if (!ViewEdit( (uiOption == EDIT_OPTION) ? TRUE : FALSE))
{
bRepaint = FALSE;
}
break;
case HEX_OPTION:
ViewDisable();
bViewHexFlag = !bViewHexFlag;
break;
case SEARCH_OPTION:
switch (pBlkHdr->ui8BlkType)
{
case BT_NON_LEAF_COUNTS:
case BT_NON_LEAF:
case BT_LEAF_DATA:
case BT_LEAF:
gv_uiViewSearchLfNum =
(FLMUINT)(((F_BTREE_BLK_HDR *)pBlkHdr)->ui16LogicalFile);
gv_uiViewSearchLfType =
getBlkLfType( (F_BTREE_BLK_HDR *)pBlkHdr);
if (ViewGetKey())
{
gv_bViewPoppingStack = TRUE;
}
break;
case BT_LFH_BLK:
{
VIEW_MENU_ITEM_p pMenuItem = gv_pViewMenuCurrItem;
// Determine which logical file, if any we are pointing at
while (pMenuItem &&
pMenuItem->iLabelIndex != LBL_LOGICAL_FILE_NAME)
{
pMenuItem = pMenuItem->pPrevItem;
}
if (pMenuItem)
{
while (pMenuItem &&
pMenuItem->iLabelIndex != LBL_LOGICAL_FILE_NUMBER)
{
pMenuItem = pMenuItem->pNextItem;
}
}
if (pMenuItem)
{
FLMBYTE * pszTmp;
gv_uiViewSearchLfNum = (FLMUINT)pMenuItem->ui64Value;
while (pMenuItem &&
pMenuItem->iLabelIndex != LBL_LOGICAL_FILE_TYPE)
{
pMenuItem = pMenuItem->pNextItem;
}
pszTmp = (FLMBYTE *)((FLMUINT)pMenuItem->ui64Value);
if (f_stricmp( (const char *)pszTmp, COLLECTION_STRING) == 0)
{
gv_uiViewSearchLfType = XFLM_LF_COLLECTION;
}
else
{
gv_uiViewSearchLfType = XFLM_LF_INDEX;
}
if (ViewGetKey())
{
gv_bViewPoppingStack = TRUE;
}
}
else
{
ViewShowError(
"Position cursor to a logical file before searching");
}
}
break;
default:
ViewShowError(
"This block does not belong to a logical file - cannot search");
break;
}
break;
default:
if (uiOption & LOGICAL_INDEX_OPTION)
{
ViewLogicalFile( (FLMUINT)(uiOption &
(~(LOGICAL_INDEX_OPTION))), XFLM_LF_INDEX);
}
else if (uiOption & LOGICAL_CONTAINER_OPTION)
{
ViewLogicalFile( (FLMUINT)(uiOption &
(~(LOGICAL_CONTAINER_OPTION))), XFLM_LF_COLLECTION);
}
else if (uiOption & LFH_OPTION_ROOT_BLOCK)
{
F_LF_HDR * pLfHdr = (F_LF_HDR *)((FLMBYTE *)pBlkHdr +
SIZEOF_STD_BLK_HDR);
pLfHdr += (uiOption & 0xFFFF);
BlkExp2.uiLevel = 0xFF;
BlkExp2.uiType = 0xFF;
uiBlkAddress2 = (FLMUINT)pLfHdr->ui32RootBlkAddr;
BlkExp2.uiLfNum = (FLMUINT)pLfHdr->ui32LfNumber;
BlkExp2.uiNextAddr = BlkExp2.uiPrevAddr = 0;
ViewBlocks( uiBlkAddress2, uiBlkAddress2, &BlkExp2);
}
else if (uiOption & BLK_OPTION_CHILD_BLOCK)
{
uiBlkAddress2 = (FLMUINT)gv_pViewMenuCurrItem->ui64Value;
f_memcpy( &BlkExp2, pBlkExp, sizeof( BLK_EXP));
BlkExp2.uiNextAddr = 0xFFFFFFFF;
BlkExp2.uiPrevAddr = 0xFFFFFFFF;
BlkExp2.uiLevel = 0xFF;
BlkExp2.uiType = 0xFF;
ViewBlocks( uiBlkAddress2, uiBlkAddress2, &BlkExp2);
}
else if (uiOption & BLK_OPTION_DATA_BLOCK)
{
uiBlkAddress2 = (FLMUINT)gv_pViewMenuCurrItem->ui64Value;
f_memcpy( &BlkExp2, pBlkExp, sizeof( BLK_EXP));
BlkExp2.uiNextAddr = 0xFFFFFFFF;
BlkExp2.uiPrevAddr = 0xFFFFFFFF;
BlkExp2.uiLevel = 0xFF;
BlkExp2.uiType = 0xFF;
ViewBlocks( uiBlkAddress2, uiBlkAddress2, &BlkExp2);
}
else
{
bRepaint = FALSE;
}
break;
}
}
Exit:
f_free( &pBlkHdr);
ViewRestore( &SaveView);
}
/********************************************************************
Desc: Have user enter a block address.
*********************************************************************/
FLMBOOL GetBlockAddrType(
FLMUINT * puiBlkAddress
)
{
FLMBOOL bGotAddress = FALSE;
FLMBOOL bBadDigit;
char szTempBuf [20];
FLMUINT uiLoop;
FLMUINT uiChar;
FLMUINT uiNumCols;
FLMUINT uiNumRows;
f_conGetScreenSize( &uiNumCols, &uiNumRows);
// Get the block address
for (;;)
{
bBadDigit = FALSE;
f_conSetBackFore( FLM_BLACK, FLM_WHITE);
f_conClearScreen( 0, uiNumRows - 2);
ViewAskInput(
"Enter Block Address (in hex): ",
szTempBuf, sizeof( szTempBuf));
if (f_stricmp( szTempBuf, "\\") == 0 || !szTempBuf [0])
{
break;
}
uiLoop = 0;
*puiBlkAddress = 0;
while (szTempBuf [uiLoop] && uiLoop < 8)
{
(*puiBlkAddress) <<= 4;
uiChar = (FLMUINT)szTempBuf [uiLoop];
if (uiChar >= '0' && uiChar <= '9')
{
(*puiBlkAddress) += (FLMUINT)(uiChar - '0');
}
else if (uiChar >= 'a' && uiChar <= 'f')
{
(*puiBlkAddress) += (FLMUINT)(uiChar - 'a' + 10);
}
else if (uiChar >= 'A' && uiChar<= 'F')
{
(*puiBlkAddress) += (FLMUINT)(uiChar - 'A' + 10);
}
else
{
bBadDigit = TRUE;
break;
}
uiLoop++;
}
if (bBadDigit)
{
ViewShowError(
"Illegal digit in number - must be hex digits");
}
else if (szTempBuf [uiLoop])
{
ViewShowError( "Too many characters in number");
}
else
{
bGotAddress = TRUE;
break;
}
}
f_conClearScreen( 0, uiNumRows - 2);
ViewEscPrompt();
return( bGotAddress);
}
/********************************************************************
Desc: ?
*********************************************************************/
FSTATIC void SetSearchTopBottom( void)
{
if (!gv_pViewSearchItem)
{
gv_pViewMenuCurrItem = NULL;
gv_uiViewMenuCurrItemNum = 0;
gv_uiViewCurrFileOffset = 0;
gv_uiViewCurrFileNumber = 0;
gv_uiViewTopRow = 0;
}
else
{
gv_pViewMenuCurrItem = gv_pViewSearchItem;
gv_uiViewMenuCurrItemNum = gv_pViewSearchItem->uiItemNum;
gv_uiViewCurrFileOffset = gv_pViewSearchItem->uiModFileOffset;
gv_uiViewCurrFileNumber = gv_pViewSearchItem->uiModFileNumber;
gv_uiViewTopRow = gv_pViewSearchItem->uiRow;
if (gv_uiViewTopRow < LINES_PER_PAGE / 2)
{
gv_uiViewTopRow = 0;
}
else
{
gv_uiViewTopRow -= (LINES_PER_PAGE / 2);
}
}
gv_uiViewBottomRow = gv_uiViewTopRow + LINES_PER_PAGE - 1;
if (gv_uiViewBottomRow > gv_pViewMenuLastItem->uiRow)
{
gv_uiViewBottomRow = gv_pViewMenuLastItem->uiRow;
if (gv_uiViewBottomRow < LINES_PER_PAGE)
{
gv_uiViewTopRow = 0;
}
else
{
gv_uiViewTopRow = gv_uiViewBottomRow - LINES_PER_PAGE + 1;
}
}
}
/*=============================================================================
Desc:
=============================================================================*/
FSTATIC void GetElmInfo(
FLMBYTE * pucEntry,
F_BTREE_BLK_HDR * pBlkHdr,
STATE_INFO * pStateInfo
)
{
F_NodeVerifier * pNodeVerifier = pStateInfo->pNodeVerifier;
f_memset( pStateInfo, 0, sizeof(STATE_INFO));
pStateInfo->pNodeVerifier = pNodeVerifier;
pStateInfo->pBlkHdr = (F_BLK_HDR *)pBlkHdr;
pStateInfo->ui32BlkAddress = pBlkHdr->stdBlkHdr.ui32BlkAddr;
pStateInfo->pucElm = pucEntry;
pStateInfo->uiElmOffset = (FLMUINT)pucEntry - (FLMUINT)pBlkHdr;
switch ( pBlkHdr->stdBlkHdr.ui8BlkType)
{
// Leaf node - no data. Only element and key.
case BT_LEAF:
{
pStateInfo->uiElmKeyLenOffset = pStateInfo->uiElmOffset; // No flags.
pStateInfo->uiElmKeyLen = FB2UW( pucEntry);
pStateInfo->uiElmLen = pStateInfo->uiElmKeyLen + 2; // 2 byte key len
pStateInfo->uiElmKeyOffset = pStateInfo->uiElmOffset + 2; // ditto
pStateInfo->pucElmKey = &pucEntry[ 2]; // Key
break;
}
// Leaf node with data
case BT_LEAF_DATA:
{
FLMBYTE ucFlag;
FLMBYTE * pucTmp;
FLMUINT uiElmLen;
pucTmp = &pucEntry[ 1];
ucFlag = pucEntry[ 0];
uiElmLen = 1; // Flag
pStateInfo->uiElmKeyLenOffset = (FLMUINT)pucTmp - (FLMUINT)pBlkHdr;
if (bteKeyLenFlag( pucEntry))
{
uiElmLen += 2;
pStateInfo->uiElmKeyLen = FB2UW( pucTmp);
uiElmLen += pStateInfo->uiElmKeyLen;
pucTmp += 2;
}
else
{
uiElmLen++;
pStateInfo->uiElmKeyLen = *pucTmp;
uiElmLen += pStateInfo->uiElmKeyLen;
pucTmp++;
}
pStateInfo->uiElmDataLenOffset = (FLMUINT)pucTmp - (FLMUINT)pBlkHdr;
if (bteDataLenFlag( pucEntry))
{
uiElmLen += 2;
pStateInfo->uiElmDataLen = FB2UW( pucTmp);
uiElmLen += pStateInfo->uiElmDataLen;
pucTmp += 2;
}
else
{
uiElmLen++;
pStateInfo->uiElmDataLen = *pucTmp;
uiElmLen += pStateInfo->uiElmDataLen;
pucTmp++;
}
if (bteOADataLenFlag( pucEntry))
{
pStateInfo->uiElmOADataLen = FB2UD( pucTmp);
pStateInfo->uiElmOADataLenOffset = (FLMUINT)pucTmp - (FLMUINT)pBlkHdr;
uiElmLen += 4; // Add the OA Data Length
pucTmp += 4; // Skip over the OA Data Length
}
// Save the key pointer...
pStateInfo->pucElmKey = pucTmp;
pStateInfo->uiElmKeyOffset = (FLMUINT)pucTmp - (FLMUINT)pBlkHdr;
// Now the data
pucTmp += pStateInfo->uiElmKeyLen;
pStateInfo->pucElmData = pucTmp;
pStateInfo->uiElmDataOffset = (FLMUINT)pucTmp - (FLMUINT)pBlkHdr;
// The element length
pStateInfo->uiElmLen = uiElmLen;
break;
}
case BT_NON_LEAF:
{
FLMBYTE * pucTmp = pucEntry;
// Skip over the child block address for now.
pucTmp += 4;
// Get the key length & offset
pStateInfo->uiElmKeyLen = FB2UW( pucTmp);
pStateInfo->uiElmKeyLenOffset = (FLMUINT)pucTmp - (FLMUINT)pBlkHdr;
// Get the key and offset
pucTmp += 2;
pStateInfo->pucElmKey = pucTmp;
pStateInfo->uiElmKeyOffset = (FLMUINT)pucTmp - (FLMUINT)pBlkHdr;
// The element length
pStateInfo->uiElmLen = pStateInfo->uiElmKeyLen + 6;
break;
}
case BT_NON_LEAF_COUNTS:
{
FLMBYTE * pucTmp = pucEntry;
// Skip over the child block address for now.
pucTmp += 4;
// Get the counts and offset
pStateInfo->uiElmCounts = FB2UD( pucTmp);
pStateInfo->uiElmCountsOffset = (FLMUINT)pucTmp - (FLMUINT)pBlkHdr;
// Get the key length & offset
pucTmp += 4;
pStateInfo->uiElmKeyLen = FB2UW( pucTmp);
pStateInfo->uiElmKeyLenOffset = (FLMUINT)pucTmp - (FLMUINT)pBlkHdr;
// Get the key and offset
pucTmp += 2;
pStateInfo->pucElmKey = pucTmp;
pStateInfo->uiElmKeyOffset = (FLMUINT)pucTmp - (FLMUINT)pBlkHdr;
// The element length
pStateInfo->uiElmLen = pStateInfo->uiElmKeyLen + 10;
break;
}
case BT_DATA_ONLY:
{
FLMBYTE * pucTmp = pucEntry;
if (!pBlkHdr->stdBlkHdr.ui32PrevBlkInChain)
{
pStateInfo->uiElmKeyLen = (FLMUINT)FB2UW( pucTmp);
pStateInfo->uiElmKeyLenOffset = (FLMUINT)pucTmp - (FLMUINT)pBlkHdr;
pucTmp += 2;
pStateInfo->pucElmKey = pucTmp;
pStateInfo->uiElmKeyOffset = (FLMUINT)pucTmp - (FLMUINT)pBlkHdr;
pucTmp += pStateInfo->uiElmKeyLen;
}
else
{
pStateInfo->uiElmKeyLen = 0;
}
pStateInfo->uiElmLen = gv_ViewDbHdr.ui16BlockSize -
pBlkHdr->stdBlkHdr.ui16BlkBytesAvail;
pStateInfo->uiElmDataLen = pStateInfo->uiElmLen -
pStateInfo->uiElmKeyLen;
pStateInfo->pucElmData = pucTmp +
(pStateInfo->uiElmKeyLen ? pStateInfo->uiElmKeyLen + 2 : 0);
}
}
}