git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@1009 0109f412-320b-0410-ab79-c3e0c5ffbbe6
2816 lines
74 KiB
C++
2816 lines
74 KiB
C++
//-------------------------------------------------------------------------
|
||
// Desc: View database blocks.
|
||
// Tabs: 3
|
||
//
|
||
// Copyright (c) 1992-2007 Novell, Inc. All Rights Reserved.
|
||
//
|
||
// This library is free software; you can redistribute it and/or
|
||
// modify it under the terms of the GNU Lesser General Public
|
||
// License as published by the Free Software Foundation; version 2.1
|
||
// of the License.
|
||
//
|
||
// This library 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
|
||
// Library Lesser General Public License for more details.
|
||
//
|
||
// You should have received a copy of the GNU Lesser General Public
|
||
// License along with this library; 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$
|
||
//------------------------------------------------------------------------------
|
||
|
||
#include "view.h"
|
||
|
||
FSTATIC void InitStatusBits(
|
||
FLMBYTE * StatusBytes);
|
||
|
||
FSTATIC void OrStatusBits(
|
||
FLMBYTE * DestStatusBytes,
|
||
FLMBYTE * SrcStatusBytes);
|
||
|
||
FSTATIC void SetStatusBit(
|
||
FLMBYTE * StatusBytes,
|
||
eCorruptionType eCorruptionCode);
|
||
|
||
FSTATIC FLMBOOL TestStatusBit(
|
||
FLMBYTE * StatusBytes,
|
||
eCorruptionType eCorruptionCode);
|
||
|
||
FSTATIC FLMINT OutputElmRecord(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
eColorType bc,
|
||
eColorType fc,
|
||
FLMUINT LabelWidth,
|
||
STATE_INFO * StateInfo,
|
||
FLMBYTE * StatusBytes,
|
||
FLMUINT StatusOnlyFlag);
|
||
|
||
FSTATIC FLMINT OutBlkHdrExpNum(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
eColorType bc,
|
||
eColorType fc,
|
||
eColorType mbc,
|
||
eColorType mfc,
|
||
eColorType sbc,
|
||
eColorType sfc,
|
||
FLMUINT LabelWidth,
|
||
FLMINT iLabelIndex,
|
||
FLMUINT FileNumber,
|
||
FLMUINT FileOffset,
|
||
FLMBYTE * ValuePtr,
|
||
FLMUINT ValueType,
|
||
FLMUINT ModType,
|
||
FLMUINT ExpNum,
|
||
FLMUINT IgnoreExpNum,
|
||
FLMUINT Option);
|
||
|
||
FSTATIC void FormatBlkType(
|
||
FLMBYTE * TempBuf,
|
||
FLMUINT BlkType);
|
||
|
||
FSTATIC FLMINT OutputStatus(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
eColorType bc,
|
||
eColorType fc,
|
||
FLMUINT LabelWidth,
|
||
FLMINT iLabelIndex,
|
||
FLMBYTE * StatusFlags);
|
||
|
||
FSTATIC FLMINT OutputHexValue(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
eColorType bc,
|
||
eColorType fc,
|
||
FLMINT LabelIndex,
|
||
FLMUINT FileNumber,
|
||
FLMUINT FileOffset,
|
||
FLMBYTE * ValPtr,
|
||
FLMUINT ValLen,
|
||
FLMUINT CopyVal,
|
||
FLMUINT uiModFlag);
|
||
|
||
FSTATIC FLMINT OutputLeafElements(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
FLMBYTE * BlkPtr,
|
||
BLK_EXP_p BlkExp,
|
||
FLMBYTE * BlkStatusRV,
|
||
FLMUINT StatusOnlyFlag,
|
||
FLMBOOL bEncrypted);
|
||
|
||
FSTATIC FLMINT OutputNonLeafElements(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
FLMBYTE * BlkPtr,
|
||
BLK_EXP_p BlkExp,
|
||
FLMBYTE * BlkStatusRV,
|
||
FLMUINT StatusOnlyFlag,
|
||
FLMBOOL bEncrypted);
|
||
|
||
FSTATIC void SetSearchTopBottom(
|
||
void
|
||
);
|
||
|
||
extern FLMUINT gv_uiTopLine;
|
||
extern FLMUINT gv_uiBottomLine;
|
||
|
||
/********************************************************************
|
||
Desc: ?
|
||
*********************************************************************/
|
||
FSTATIC void InitStatusBits(
|
||
FLMBYTE * StatusBytes
|
||
)
|
||
{
|
||
FLMUINT i;
|
||
|
||
if (StatusBytes != NULL)
|
||
{
|
||
for( i = 0; i < NUM_STATUS_BYTES; i++)
|
||
StatusBytes [i] = 0;
|
||
}
|
||
}
|
||
|
||
/********************************************************************
|
||
Desc: ?
|
||
*********************************************************************/
|
||
FSTATIC void OrStatusBits(
|
||
FLMBYTE * DestStatusBytes,
|
||
FLMBYTE * SrcStatusBytes
|
||
)
|
||
{
|
||
FLMUINT i;
|
||
|
||
if ((DestStatusBytes != NULL) && (SrcStatusBytes != NULL))
|
||
{
|
||
for( i = 0; i < NUM_STATUS_BYTES; i++)
|
||
DestStatusBytes [i] |= SrcStatusBytes [i];
|
||
}
|
||
}
|
||
|
||
/********************************************************************
|
||
Desc: ?
|
||
*********************************************************************/
|
||
FSTATIC void SetStatusBit(
|
||
FLMBYTE * StatusBytes,
|
||
eCorruptionType eCorruptionCode
|
||
)
|
||
{
|
||
FLMUINT ByteOffset = ((FLMUINT)eCorruptionCode - 1) / 8;
|
||
FLMBYTE BitToSet = (FLMBYTE)0x80 >> (FLMBYTE)(((FLMUINT)eCorruptionCode - 1) % 8);
|
||
|
||
if (StatusBytes != NULL)
|
||
StatusBytes [ByteOffset] |= BitToSet;
|
||
}
|
||
|
||
/********************************************************************
|
||
Desc: ?
|
||
*********************************************************************/
|
||
FSTATIC FLMBOOL TestStatusBit(
|
||
FLMBYTE * StatusBytes,
|
||
eCorruptionType eCorruptionCode
|
||
)
|
||
{
|
||
if (eCorruptionCode == FLM_NO_CORRUPTION)
|
||
{
|
||
return( FALSE);
|
||
}
|
||
else
|
||
{
|
||
FLMUINT ByteOffset = ((FLMUINT)eCorruptionCode - 1) / 8;
|
||
FLMBYTE BitToTest = (FLMBYTE)0x80 >> (FLMBYTE)(((FLMUINT)eCorruptionCode - 1) % 8);
|
||
|
||
if (StatusBytes == NULL)
|
||
{
|
||
return( FALSE);
|
||
}
|
||
else
|
||
{
|
||
return( (StatusBytes [ByteOffset] & BitToTest) ? TRUE : FALSE);
|
||
}
|
||
}
|
||
}
|
||
|
||
/***************************************************************************
|
||
Name: OutputStatus
|
||
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 FLMINT OutputStatus(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
eColorType bc,
|
||
eColorType fc,
|
||
FLMUINT LabelWidth,
|
||
FLMINT iLabelIndex,
|
||
FLMBYTE * StatusFlags)
|
||
{
|
||
FLMUINT Row = *RowRV;
|
||
FLMUINT HadError = FALSE;
|
||
FLMUINT uiLoop;
|
||
|
||
/* Output each error on a separate line */
|
||
|
||
if (StatusFlags)
|
||
{
|
||
for( uiLoop = (FLMUINT)FLM_NO_CORRUPTION + 1; uiLoop < (FLMUINT)FLM_LAST_CORRUPT_ERROR; uiLoop++)
|
||
{
|
||
if (TestStatusBit( StatusFlags, (eCorruptionType)uiLoop))
|
||
{
|
||
HadError = TRUE;
|
||
if (!ViewAddMenuItem( iLabelIndex, LabelWidth,
|
||
VAL_IS_ERR_INDEX, (FLMUINT)uiLoop, 0,
|
||
0, VIEW_INVALID_FILE_OFFSET, 0, MOD_DISABLED,
|
||
Col, Row++, 0,
|
||
FLM_RED, FLM_LIGHTGRAY,
|
||
FLM_RED, FLM_LIGHTGRAY))
|
||
return( 0);
|
||
|
||
/* 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 (!HadError)
|
||
{
|
||
if (!ViewAddMenuItem( iLabelIndex, LabelWidth,
|
||
VAL_IS_LABEL_INDEX, (FLMUINT)LBL_OK, 0,
|
||
0, VIEW_INVALID_FILE_OFFSET, 0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
}
|
||
*RowRV = Row;
|
||
return( 1);
|
||
}
|
||
|
||
/********************************************************************
|
||
Desc: ?
|
||
*********************************************************************/
|
||
FSTATIC FLMINT OutputElmRecord(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
eColorType bc,
|
||
eColorType fc,
|
||
FLMUINT LabelWidth,
|
||
STATE_INFO * StateInfo,
|
||
FLMBYTE * StatusBytes,
|
||
FLMUINT StatusOnlyFlag)
|
||
{
|
||
eCorruptionType eCorruptionCode;
|
||
FLMUINT SaveElmRecOffset;
|
||
FLMBYTE FOPStatusBytes [NUM_STATUS_BYTES];
|
||
FLMUINT FOPType;
|
||
FLMUINT FieldType;
|
||
FLMUINT Row = *RowRV;
|
||
FLMUINT FileOffset;
|
||
FLMUINT FileNumber;
|
||
FLMUINT FldOverhead;
|
||
FLMBYTE * FieldPtr;
|
||
FLMUINT FldFlags;
|
||
|
||
for( ;;)
|
||
{
|
||
InitStatusBits( FOPStatusBytes);
|
||
SaveElmRecOffset = StateInfo->uiElmRecOffset;
|
||
FieldPtr = &StateInfo->pElmRec [SaveElmRecOffset];
|
||
FileOffset = StateInfo->uiBlkAddress +
|
||
(StateInfo->pElmRec - StateInfo->pBlk) +
|
||
SaveElmRecOffset;
|
||
FileNumber = FSGetFileNumber( StateInfo->uiBlkAddress);
|
||
|
||
if ((eCorruptionCode = flmVerifyElmFOP( StateInfo)) != FLM_NO_CORRUPTION)
|
||
{
|
||
SetStatusBit( FOPStatusBytes, eCorruptionCode);
|
||
SetStatusBit( StatusBytes, eCorruptionCode);
|
||
}
|
||
|
||
/* Output the field overhead */
|
||
|
||
if (!StatusOnlyFlag)
|
||
{
|
||
Row++;
|
||
|
||
/* First output the FOP type */
|
||
|
||
switch( StateInfo->uiFOPType)
|
||
{
|
||
case FLM_FOP_CONT_DATA:
|
||
FOPType = LBL_FOP_CONT;
|
||
FldOverhead = 0;
|
||
break;
|
||
case FLM_FOP_STANDARD:
|
||
FOPType = LBL_FOP_STD;
|
||
FldOverhead = 2;
|
||
break;
|
||
case FLM_FOP_OPEN:
|
||
FOPType = LBL_FOP_OPEN;
|
||
FldFlags = FOP_GET_FLD_FLAGS( FieldPtr);
|
||
FldOverhead = ((FOP_2BYTE_FLDNUM( FldFlags)) ? 3 : 2) +
|
||
((FOP_2BYTE_FLDLEN( FldFlags)) ? 2 : 1);
|
||
break;
|
||
case FLM_FOP_TAGGED:
|
||
FOPType = LBL_FOP_TAGGED;
|
||
FldFlags = FOP_GET_FLD_FLAGS( FieldPtr);
|
||
FldOverhead = ((FOP_2BYTE_FLDNUM( FldFlags)) ? 4 : 3) +
|
||
((FOP_2BYTE_FLDLEN( FldFlags)) ? 2 : 1);
|
||
break;
|
||
case FLM_FOP_NO_VALUE:
|
||
FOPType = LBL_FOP_NO_VALUE;
|
||
FldFlags = FOP_GET_FLD_FLAGS( FieldPtr);
|
||
FldOverhead = ((FOP_2BYTE_FLDNUM( FldFlags)) ? 3 : 2);
|
||
break;
|
||
case FLM_FOP_JUMP_LEVEL:
|
||
FOPType = LBL_FOP_SET_LEVEL;
|
||
FldOverhead = 1;
|
||
break;
|
||
case FLM_FOP_REC_INFO:
|
||
FOPType = LBL_FOP_REC_INFO;
|
||
FldFlags = FOP_GET_FLD_FLAGS( FieldPtr);
|
||
FldOverhead = ((FOP_2BYTE_FLDLEN( FldFlags)) ? 3 : 2);
|
||
break;
|
||
case FLM_FOP_ENCRYPTED:
|
||
FOPType = LBL_FOP_ENCRYPTED;
|
||
FldFlags = 0;
|
||
FldOverhead = 2;
|
||
break;
|
||
case FLM_FOP_BAD:
|
||
default:
|
||
FOPType = LBL_FOP_BAD;
|
||
FldOverhead = 0;
|
||
break;
|
||
}
|
||
if (!ViewAddMenuItem( LBL_FOP_TYPE, LabelWidth,
|
||
VAL_IS_LABEL_INDEX, (FLMUINT)FOPType, 0,
|
||
FileNumber, FileOffset, FldOverhead,
|
||
(FLMBYTE)(MOD_BINARY | (FLMBYTE)(!FldOverhead
|
||
? (FLMBYTE)MOD_DISABLED
|
||
: (FLMBYTE)0)),
|
||
Col, Row++, 0, FLM_BLUE, FLM_LIGHTGRAY,
|
||
FLM_BLUE, FLM_LIGHTGRAY))
|
||
return( 0);
|
||
|
||
/* Output the offset of the field within the element record */
|
||
|
||
if (!ViewAddMenuItem( LBL_FIELD_OFFSET, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)SaveElmRecOffset, 0,
|
||
FileNumber, FileOffset, 0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
|
||
/* Output the field number, field type, and field level if applicable */
|
||
|
||
if ((StateInfo->uiFOPType != FLM_FOP_CONT_DATA) &&
|
||
(StateInfo->uiFOPType != FLM_FOP_JUMP_LEVEL) &&
|
||
(StateInfo->uiFOPType != FLM_FOP_BAD) &&
|
||
(StateInfo->uiFOPType != FLM_FOP_NEXT_DRN) &&
|
||
(StateInfo->uiFOPType != FLM_FOP_REC_INFO) &&
|
||
(eCorruptionCode != FLM_BAD_ELM_FLD_OVERHEAD))
|
||
{
|
||
if (!ViewAddMenuItem( LBL_FIELD_NUMBER, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo->uiFieldNum, 0,
|
||
FileNumber, FileOffset, 0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
|
||
/* Output the field type */
|
||
|
||
switch( StateInfo->uiFieldType)
|
||
{
|
||
case FLM_TEXT_TYPE:
|
||
FieldType = LBL_TYPE_TEXT;
|
||
break;
|
||
case FLM_NUMBER_TYPE:
|
||
FieldType = LBL_TYPE_NUMBER;
|
||
break;
|
||
case FLM_BINARY_TYPE:
|
||
FieldType = LBL_TYPE_BINARY;
|
||
break;
|
||
case FLM_CONTEXT_TYPE:
|
||
FieldType = LBL_TYPE_CONTEXT;
|
||
break;
|
||
default:
|
||
FieldType = LBL_TYPE_UNKNOWN;
|
||
break;
|
||
}
|
||
if (!ViewAddMenuItem( LBL_FIELD_TYPE, LabelWidth,
|
||
VAL_IS_LABEL_INDEX, (FLMUINT)FieldType, 0,
|
||
FileNumber, FileOffset, 0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
|
||
/* Output the field level */
|
||
|
||
if (!ViewAddMenuItem( LBL_FIELD_LEVEL, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo->uiFieldLevel, 0,
|
||
FileNumber, FileOffset, 0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
|
||
if (StateInfo->uiEncId)
|
||
{
|
||
if (!ViewAddMenuItem( LBL_ENC_ID, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo->uiEncId, 0,
|
||
FileNumber, FileOffset, 0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
}
|
||
}
|
||
|
||
/* Output the jump level for the jump FOP */
|
||
|
||
if (StateInfo->uiFOPType == FLM_FOP_JUMP_LEVEL)
|
||
{
|
||
if (!ViewAddMenuItem( LBL_JUMP_LEVEL, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo->uiJumpLevel, 0,
|
||
FileNumber, FileOffset, 0x07, MOD_BITS | MOD_DECIMAL,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
}
|
||
|
||
/* Output the field data length */
|
||
|
||
if (eCorruptionCode != FLM_BAD_ELM_FLD_OVERHEAD)
|
||
{
|
||
if (!ViewAddMenuItem( LBL_FIELD_LENGTH, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
StateInfo->uiFOPDataLen, 0,
|
||
FileNumber, FileOffset, 0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
}
|
||
}
|
||
|
||
/* Verify the field if it is entirely contained right here */
|
||
|
||
if ((eCorruptionCode == FLM_NO_CORRUPTION) &&
|
||
(StateInfo->uiFOPDataLen == (StateInfo->uiEncId
|
||
? StateInfo->uiEncFieldLen
|
||
: StateInfo->uiFieldLen) &&
|
||
(StateInfo->uiFOPDataLen > 0) &&
|
||
(StateInfo->uiFOPType != FLM_FOP_CONT_DATA)))
|
||
{
|
||
if (StateInfo->uiFOPType == FLM_FOP_REC_INFO)
|
||
{
|
||
eCorruptionCode = FLM_NO_CORRUPTION;
|
||
}
|
||
else
|
||
{
|
||
eCorruptionCode = flmVerifyField( StateInfo, StateInfo->pFOPData,
|
||
StateInfo->uiFOPDataLen,
|
||
StateInfo->uiFieldType);
|
||
}
|
||
if (eCorruptionCode != FLM_NO_CORRUPTION)
|
||
{
|
||
SetStatusBit( FOPStatusBytes, eCorruptionCode);
|
||
SetStatusBit( StatusBytes, eCorruptionCode);
|
||
}
|
||
}
|
||
|
||
/* Output the field status */
|
||
|
||
if ((!StatusOnlyFlag) && (eCorruptionCode != FLM_NO_CORRUPTION))
|
||
{
|
||
if (!OutputStatus( Col, &Row, bc, fc, LabelWidth,
|
||
LBL_FIELD_STATUS, FOPStatusBytes))
|
||
return( 0);
|
||
}
|
||
|
||
/* Output the data. If we had a bad overhead error, output */
|
||
/* the rest of the data in the element. */
|
||
|
||
if ((eCorruptionCode == FLM_BAD_ELM_FLD_OVERHEAD) ||
|
||
((eCorruptionCode != FLM_NO_CORRUPTION) &&
|
||
(StateInfo->uiElmRecOffset == SaveElmRecOffset)))
|
||
{
|
||
*RowRV = Row;
|
||
if (StatusOnlyFlag)
|
||
return( 1);
|
||
return( OutputHexValue( Col, RowRV, bc, fc,
|
||
(FLMUINT)((SaveElmRecOffset == 0)
|
||
? (FLMUINT)LBL_RECORD
|
||
: (FLMUINT)LBL_FIELD_DATA),
|
||
FileNumber, FileOffset,
|
||
&StateInfo->pElmRec [SaveElmRecOffset],
|
||
(FLMUINT)(StateInfo->uiElmRecLen - SaveElmRecOffset),
|
||
FALSE, MOD_BINARY));
|
||
}
|
||
else if ((!StatusOnlyFlag) && (StateInfo->uiFOPDataLen))
|
||
{
|
||
if (!OutputHexValue( Col, &Row, bc, fc, LBL_FIELD_DATA,
|
||
FSGetFileNumber( StateInfo->uiBlkAddress),
|
||
FSGetFileOffset( StateInfo->uiBlkAddress) +
|
||
(FLMUINT)(StateInfo->pFOPData - StateInfo->pBlk),
|
||
StateInfo->pFOPData,
|
||
StateInfo->uiFOPDataLen, FALSE, MOD_BINARY))
|
||
return( 0);
|
||
}
|
||
|
||
/* See if we have reached the end of the element - or quit */
|
||
/* if the element record offset is not changing */
|
||
|
||
if (StateInfo->uiElmRecOffset >= StateInfo->uiElmRecLen)
|
||
{
|
||
*RowRV = Row;
|
||
return( 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/***************************************************************************
|
||
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.
|
||
*****************************************************************************/
|
||
FLMINT ViewBlkRead(
|
||
FLMUINT BlkAddress,
|
||
FLMBYTE ** BlkPtrRV,
|
||
FLMUINT ReadLen,
|
||
FLMUINT16 * pui16CalcChkSum,
|
||
FLMUINT16 * pui16BlkChkSum,
|
||
FLMUINT * puiBytesReadRV,
|
||
FLMBOOL bShowPartialReadError,
|
||
FLMBOOL * pbIsEncBlock,
|
||
FLMBOOL bDecryptBlock,
|
||
FLMBOOL * pbEncrypted
|
||
)
|
||
{
|
||
RCODE rc;
|
||
FLMBYTE * BlkPtr;
|
||
char szErrMsg [80];
|
||
|
||
/* First allocate memory to read the block into */
|
||
/* if not already allocated */
|
||
|
||
if (!(*BlkPtrRV))
|
||
{
|
||
if (RC_BAD( rc = f_alloc( ReadLen, BlkPtrRV)))
|
||
{
|
||
ViewShowRCError( "allocating memory to read block", rc);
|
||
return( 0);
|
||
}
|
||
}
|
||
BlkPtr = *BlkPtrRV;
|
||
|
||
/* Read the block into memory - if block address is zero, don't */
|
||
/* read the first byte of the file. */
|
||
|
||
if (BlkAddress == 0)
|
||
{
|
||
BlkAddress++;
|
||
*BlkPtr++ = 0xFF;
|
||
ReadLen--;
|
||
}
|
||
|
||
if (RC_BAD( rc = gv_pSFileHdl->readBlock( BlkAddress, ReadLen,
|
||
BlkPtr, puiBytesReadRV)))
|
||
{
|
||
if (rc == FERR_IO_END_OF_FILE)
|
||
{
|
||
rc = FERR_OK;
|
||
f_memset( &BlkPtr [*puiBytesReadRV], 0xEE, ReadLen - *puiBytesReadRV);
|
||
if (bShowPartialReadError)
|
||
{
|
||
if (!(*puiBytesReadRV))
|
||
{
|
||
ViewShowRCError( "reading block", FERR_IO_END_OF_FILE);
|
||
return( 0);
|
||
}
|
||
else if (*puiBytesReadRV < ReadLen)
|
||
{
|
||
f_sprintf( szErrMsg,
|
||
"Only %u bytes of data were read (requested %u)",
|
||
(unsigned)*puiBytesReadRV, (unsigned)ReadLen);
|
||
ViewShowError( szErrMsg);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ViewShowRCError( "reading block", rc);
|
||
return( 0);
|
||
}
|
||
}
|
||
|
||
if (pui16BlkChkSum)
|
||
{
|
||
*pui16BlkChkSum = (FLMUINT16)(((FLMUINT)BlkPtr [BH_CHECKSUM_HIGH] << 8) +
|
||
BlkPtr [BH_CHECKSUM_LOW]);
|
||
}
|
||
|
||
/* Decrypt the block if necessary */
|
||
|
||
if (pui16CalcChkSum != NULL)
|
||
{
|
||
if (FB2UW( &BlkPtr [BH_BLK_END]) >
|
||
gv_ViewHdrInfo.FileHdr.uiBlockSize)
|
||
{
|
||
*pui16CalcChkSum = 0;
|
||
}
|
||
else
|
||
{
|
||
FLMBYTE ucChecksumHigh = BlkPtr [BH_CHECKSUM_HIGH];
|
||
FLMBYTE ucChecksumLow = BlkPtr [BH_CHECKSUM_LOW];
|
||
|
||
BlkCheckSum( BlkPtr, CHECKSUM_SET, BlkAddress,
|
||
gv_ViewHdrInfo.FileHdr.uiBlockSize);
|
||
|
||
*pui16CalcChkSum = (FLMUINT16)(((FLMUINT)BlkPtr [BH_CHECKSUM_HIGH] << 8) +
|
||
BlkPtr [BH_CHECKSUM_LOW]);
|
||
|
||
BlkPtr [BH_CHECKSUM_HIGH] = ucChecksumHigh;
|
||
BlkPtr [BH_CHECKSUM_LOW] = ucChecksumLow;
|
||
|
||
// 3x Format demands we write over the checksum value.
|
||
|
||
BlkPtr [BH_CHECKSUM_LOW] = (FLMBYTE) BlkAddress;
|
||
}
|
||
}
|
||
|
||
if (pbEncrypted || pbIsEncBlock || bDecryptBlock)
|
||
{
|
||
FLMUINT uiBlkType = BH_GET_TYPE( BlkPtr);
|
||
FLMUINT uiLfNum = FB2UW( &BlkPtr [BH_LOG_FILE_NUM]);
|
||
FLMUINT uiBufLen = getEncryptSize( BlkPtr);
|
||
FLMUINT uiEncLen = uiBufLen - BH_OVHD;
|
||
LFILE * pLFile;
|
||
IXD * pIxd;
|
||
FDB * pDb;
|
||
FFILE * pFile;
|
||
|
||
if (pbEncrypted)
|
||
{
|
||
*pbEncrypted = FALSE;
|
||
}
|
||
if (pbIsEncBlock)
|
||
{
|
||
*pbIsEncBlock = FALSE;
|
||
}
|
||
|
||
if (uiEncLen && uiLfNum &&
|
||
uiBlkType != BHT_FREE &&
|
||
uiBlkType != BHT_LFH_BLK &&
|
||
uiBlkType != BHT_PCODE_BLK)
|
||
{
|
||
ViewGetDictInfo();
|
||
if (gv_bViewHaveDictInfo)
|
||
{
|
||
pDb = (FDB *)gv_hViewDb;
|
||
pFile = pDb->pFile;
|
||
if (RC_OK( fdictGetIndex( pDb->pDict, pFile->bInLimitedMode,
|
||
uiLfNum, &pLFile, &pIxd, TRUE)) &&
|
||
pIxd && pIxd->uiEncId)
|
||
{
|
||
if (pbEncrypted)
|
||
{
|
||
*pbEncrypted = TRUE;
|
||
}
|
||
if (pbIsEncBlock)
|
||
{
|
||
*pbIsEncBlock = TRUE;
|
||
}
|
||
#ifdef FLM_USE_NICI
|
||
if (!pFile->bInLimitedMode && bDecryptBlock)
|
||
{
|
||
F_CCS * pCcs = (F_CCS *)pFile->pDictList->pIttTbl[ pIxd->uiEncId].pvItem;
|
||
|
||
flmAssert( pCcs);
|
||
if (RC_OK( pCcs->decryptFromStore( &BlkPtr [BH_OVHD],
|
||
uiEncLen, &BlkPtr [BH_OVHD], &uiEncLen)))
|
||
{
|
||
if (pbEncrypted)
|
||
{
|
||
*pbEncrypted = FALSE;
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return( 1);
|
||
}
|
||
|
||
/***************************************************************************
|
||
Name: ViewGetLFH
|
||
Desc: This routine searches through the LFH blocks searching for the
|
||
LFH of a particular logical file.
|
||
*****************************************************************************/
|
||
FLMINT ViewGetLFH(
|
||
FLMUINT lfNum,
|
||
FLMBYTE * lfhRV,
|
||
FLMUINT * FileOffset
|
||
)
|
||
{
|
||
FLMUINT BlkAddress;
|
||
FLMUINT BlkCount = 0;
|
||
FLMBYTE * BlkPtr = NULL;
|
||
FLMUINT EndOfBlock;
|
||
FLMUINT Pos;
|
||
FLMUINT uiBytesRead;
|
||
FLMUINT GotLFH = 0;
|
||
|
||
/* Read the LFH blocks and get the information needed */
|
||
/* If we read too many, the file is probably corrupt. */
|
||
|
||
*FileOffset = 0;
|
||
BlkAddress = gv_ViewHdrInfo.FileHdr.uiFirstLFHBlkAddr;
|
||
while( BlkAddress != BT_END)
|
||
{
|
||
if ((!ViewBlkRead( BlkAddress, &BlkPtr,
|
||
gv_ViewHdrInfo.FileHdr.uiBlockSize,
|
||
NULL, NULL, &uiBytesRead, FALSE,
|
||
NULL, FALSE, NULL)) ||
|
||
(!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. */
|
||
|
||
BlkCount++;
|
||
|
||
/* Search through the block for the particular LFH which matches */
|
||
/* the one we are looking for. */
|
||
|
||
if (uiBytesRead <= BH_OVHD)
|
||
EndOfBlock = BH_OVHD;
|
||
else
|
||
{
|
||
EndOfBlock = FB2UW( &BlkPtr [BH_BLK_END]);
|
||
if (EndOfBlock > gv_ViewHdrInfo.FileHdr.uiBlockSize)
|
||
EndOfBlock = gv_ViewHdrInfo.FileHdr.uiBlockSize;
|
||
if (EndOfBlock > uiBytesRead)
|
||
EndOfBlock = uiBytesRead;
|
||
}
|
||
Pos = BH_OVHD;
|
||
while( Pos < EndOfBlock)
|
||
{
|
||
FLMUINT uiLfType;
|
||
FLMUINT uiLfNum;
|
||
|
||
/* See if we got the one we wanted */
|
||
|
||
uiLfType = BlkPtr [Pos + LFH_TYPE_OFFSET];
|
||
uiLfNum = FB2UW( &BlkPtr [Pos + LFH_LF_NUMBER_OFFSET]);
|
||
|
||
if ((uiLfType != LF_INVALID) && (lfNum == uiLfNum))
|
||
{
|
||
f_memcpy( lfhRV, &BlkPtr [Pos], LFH_SIZE);
|
||
GotLFH = 1;
|
||
*FileOffset = BlkAddress + Pos;
|
||
break;
|
||
}
|
||
|
||
Pos += LFH_SIZE;
|
||
}
|
||
|
||
/* If we didn't end right on end of block, return */
|
||
|
||
if ((Pos != EndOfBlock) || (GotLFH))
|
||
break;
|
||
|
||
/* If we have traversed too many blocks, things are probably corrupt */
|
||
|
||
if (BlkCount > 100)
|
||
break;
|
||
if (BH_NEXT_BLK + 4 <= uiBytesRead)
|
||
BlkAddress = FB2UD( &BlkPtr [BH_NEXT_BLK]);
|
||
else
|
||
BlkAddress = BT_END;
|
||
}
|
||
|
||
/* Be sure to free the block handle -- if one was allocated */
|
||
|
||
f_free( &BlkPtr);
|
||
return( GotLFH);
|
||
}
|
||
|
||
/***************************************************************************
|
||
Name: ViewGetLFName
|
||
Desc: This routine attempts to find an LFH for a particular logical
|
||
file. It then extracts the name from the LFH.
|
||
*****************************************************************************/
|
||
FLMINT ViewGetLFName(
|
||
FLMBYTE * lfName,
|
||
FLMUINT lfNum,
|
||
FLMBYTE * LFH,
|
||
FLMUINT * FileOffset)
|
||
{
|
||
FLMBYTE TempBuf [40];
|
||
|
||
if ((lfNum == 0) || (!ViewGetLFH( lfNum, LFH, FileOffset)))
|
||
{
|
||
*FileOffset = 0;
|
||
f_sprintf( (char *)TempBuf, "lfNum=%u", (unsigned)lfNum);
|
||
f_strcpy( (char *)lfName, (const char *)TempBuf);
|
||
return( 0);
|
||
}
|
||
else
|
||
{
|
||
TempBuf [0] = 0;
|
||
f_sprintf( (char *)(&TempBuf [f_strlen( (const char *)TempBuf)]), ", lfNum=%u", (unsigned)lfNum);
|
||
f_strcpy( (char *)lfName, (const char *)TempBuf);
|
||
return( 1);
|
||
}
|
||
}
|
||
|
||
/***************************************************************************
|
||
Name: OutBlkHdrExpNum
|
||
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 are expected certain values.
|
||
*****************************************************************************/
|
||
FSTATIC FLMINT OutBlkHdrExpNum(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
eColorType bc,
|
||
eColorType fc,
|
||
eColorType mbc,
|
||
eColorType mfc,
|
||
eColorType sbc,
|
||
eColorType sfc,
|
||
FLMUINT LabelWidth,
|
||
FLMINT iLabelIndex,
|
||
FLMUINT FileNumber,
|
||
FLMUINT FileOffset,
|
||
FLMBYTE * ValuePtr,
|
||
FLMUINT ValueType,
|
||
FLMUINT ModType,
|
||
FLMUINT ExpNum,
|
||
FLMUINT IgnoreExpNum,
|
||
FLMUINT Option)
|
||
{
|
||
FLMUINT Row = *RowRV;
|
||
FLMUINT Num = 0;
|
||
|
||
if (!Option)
|
||
{
|
||
mbc = sbc = bc;
|
||
mfc = sfc = fc;
|
||
}
|
||
switch( ModType & 0x0F)
|
||
{
|
||
case MOD_FLMUINT:
|
||
Num = FB2UD( ValuePtr);
|
||
break;
|
||
case MOD_FLMUINT16:
|
||
Num = FB2UW( ValuePtr);
|
||
break;
|
||
case MOD_FLMBYTE:
|
||
Num = *ValuePtr;
|
||
break;
|
||
case MOD_BH_ADDR:
|
||
Num = FB2UD( ValuePtr );/* & 0xFFFFFF00;*/ /* Could use GET_BH_ADDR() */
|
||
/* But pass in offset */
|
||
break;
|
||
}
|
||
if (!ViewAddMenuItem( iLabelIndex, LabelWidth,
|
||
ValueType, Num, 0,
|
||
FileNumber, FileOffset, 0, ModType,
|
||
Col, Row++, Option, mbc, mfc, sbc, sfc))
|
||
return( 0);
|
||
|
||
if ((ExpNum != IgnoreExpNum) && (Num != ExpNum))
|
||
{
|
||
if (!ViewAddMenuItem( LBL_EXPECTED, 0,
|
||
ValueType, ExpNum, 0,
|
||
0, VIEW_INVALID_FILE_OFFSET, 0, MOD_DISABLED,
|
||
Col + LabelWidth + 1, Row++, 0,
|
||
FLM_RED, FLM_LIGHTGRAY,
|
||
FLM_RED, FLM_LIGHTGRAY))
|
||
return( 0);
|
||
}
|
||
*RowRV = Row;
|
||
return( 1);
|
||
}
|
||
|
||
/***************************************************************************
|
||
Name: FormatBlkType
|
||
Desc: This routine formats a block's type into ASCII.
|
||
*****************************************************************************/
|
||
FSTATIC void FormatBlkType(
|
||
FLMBYTE * TempBuf,
|
||
FLMUINT BlkType
|
||
)
|
||
{
|
||
FLMBYTE TempBuf1 [30];
|
||
|
||
switch( BlkType)
|
||
{
|
||
case BHT_FREE:
|
||
f_strcpy( (char *)TempBuf, "Free");
|
||
break;
|
||
case BHT_LEAF:
|
||
f_strcpy( (char *)TempBuf, "Leaf");
|
||
break;
|
||
case BHT_NON_LEAF:
|
||
f_strcpy( (char *)TempBuf, "Non-Leaf 3x");
|
||
break;
|
||
case BHT_NON_LEAF_DATA:
|
||
f_strcpy( (char *)TempBuf, "Non-Leaf Data");
|
||
break;
|
||
case BHT_NON_LEAF_COUNTS:
|
||
f_strcpy( (char *)TempBuf, "Non-Leaf /w Counts");
|
||
break;
|
||
case BHT_LFH_BLK:
|
||
f_strcpy( (char *)TempBuf, "LFH");
|
||
break;
|
||
case BHT_PCODE_BLK:
|
||
f_strcpy( (char *)TempBuf, "PCODE");
|
||
break;
|
||
default:
|
||
f_sprintf( (char *)TempBuf1, "Unknown Type: %u", (unsigned)BlkType);
|
||
f_strcpy( (char *)TempBuf, (const char *)TempBuf1);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/***************************************************************************
|
||
Name: ViewOutBlkHdr
|
||
Desc: This routine outputs a block's header.
|
||
*****************************************************************************/
|
||
FLMINT ViewOutBlkHdr(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
FLMBYTE * BlkPtr,
|
||
BLK_EXP_p BlkExp,
|
||
FLMBYTE * BlkStatus,
|
||
FLMUINT16 ui16CalcChkSum,
|
||
FLMUINT16 ui16BlkChkSum
|
||
)
|
||
{
|
||
FLMUINT LabelWidth = 35;
|
||
FLMUINT Row = *RowRV;
|
||
FLMBYTE TempBuf [80];
|
||
FLMUINT BlkAddress;
|
||
FLMUINT EndOfBlock;
|
||
FLMUINT BytesUsed;
|
||
FLMUINT PercentFull;
|
||
FLMUINT Option;
|
||
eColorType bc = FLM_BLACK;
|
||
eColorType fc = FLM_LIGHTGRAY;
|
||
eColorType mbc = FLM_BLACK;
|
||
eColorType mfc = FLM_WHITE;
|
||
eColorType sbc = FLM_BLUE;
|
||
eColorType sfc = FLM_WHITE;
|
||
FLMBYTE lfLFH [LFH_SIZE];
|
||
FLMBYTE lfName [80];
|
||
FLMUINT lfNum;
|
||
FLMUINT lfType;
|
||
FLMUINT TempFileOffset;
|
||
FLMBYTE bySaveChar;
|
||
|
||
/* Output the block Header address */
|
||
|
||
if (!OutBlkHdrExpNum( Col, &Row, FLM_RED, FLM_LIGHTGRAY,
|
||
FLM_RED, FLM_WHITE, sbc, sfc,
|
||
LabelWidth, LBL_BLOCK_ADDRESS_BLOCK_HEADER,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr), &BlkPtr [BH_ADDR],
|
||
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
|
||
MOD_BH_ADDR | MOD_HEX,
|
||
BlkExp->BlkAddr, 0, 0))
|
||
return( 0);
|
||
|
||
/* Adjust column so rest of header is indented */
|
||
|
||
Col += 2;
|
||
LabelWidth -= 2;
|
||
|
||
/* Output the previous block address */
|
||
|
||
if (FB2UD( &BlkPtr [BH_PREV_BLK]) == BT_END)
|
||
Option = 0;
|
||
else
|
||
Option = PREV_BLOCK_OPTION;
|
||
if (!OutBlkHdrExpNum( Col, &Row, bc, fc, mbc, mfc, sbc, sfc,
|
||
LabelWidth, LBL_PREVIOUS_BLOCK_ADDRESS,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr) + BH_PREV_BLK,
|
||
&BlkPtr [BH_PREV_BLK],
|
||
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
|
||
MOD_FLMUINT | MOD_HEX,
|
||
BlkExp->PrevAddr, 0, Option))
|
||
return( 0);
|
||
|
||
/* Output the next block address */
|
||
|
||
if (FB2UD( &BlkPtr [BH_NEXT_BLK]) == BT_END)
|
||
Option = 0;
|
||
else
|
||
Option = NEXT_BLOCK_OPTION;
|
||
if (!OutBlkHdrExpNum( Col, &Row, bc, fc, mbc, mfc, sbc, sfc,
|
||
LabelWidth, LBL_NEXT_BLOCK_ADDRESS,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr) + BH_NEXT_BLK,
|
||
&BlkPtr [BH_NEXT_BLK],
|
||
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
|
||
MOD_FLMUINT | MOD_HEX,
|
||
BlkExp->NextAddr, 0, Option))
|
||
return( 0);
|
||
|
||
/* Output the logical file this block belongs to - if any */
|
||
|
||
lfNum = FB2UW( &BlkPtr [BH_LOG_FILE_NUM]);
|
||
if (!ViewGetLFName( lfName, lfNum, lfLFH, &TempFileOffset))
|
||
{
|
||
lfType = LF_INVALID;
|
||
Option = 0;
|
||
}
|
||
else
|
||
{
|
||
lfType = lfLFH [LFH_TYPE_OFFSET];
|
||
Option = LOGICAL_FILE_OPTION | lfNum;
|
||
}
|
||
if ((BlkExp->LfNum != 0) && (lfNum != BlkExp->LfNum))
|
||
f_sprintf( (char *)TempBuf, "%s (Expected %u)", lfName, (unsigned)BlkExp->LfNum);
|
||
else
|
||
f_strcpy( (char *)TempBuf, (const char *)lfName);
|
||
if (!ViewAddMenuItem( LBL_BLOCK_LOGICAL_FILE_NAME, LabelWidth,
|
||
VAL_IS_TEXT_PTR,
|
||
(FLMUINT)((FLMBYTE *)(&TempBuf [0])), 0,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr) + BH_LOG_FILE_NUM, 0,
|
||
MOD_FLMUINT | MOD_DECIMAL,
|
||
Col, Row++, Option,
|
||
!Option ? bc : mbc,
|
||
!Option ? fc : mfc,
|
||
!Option ? bc : sbc,
|
||
!Option ? fc : sfc))
|
||
return( 0);
|
||
|
||
/* Output the logical file type */
|
||
|
||
if (lfType != LF_INVALID)
|
||
{
|
||
FormatLFType( TempBuf, lfType);
|
||
if (!ViewAddMenuItem( LBL_BLOCK_LOGICAL_FILE_TYPE, LabelWidth,
|
||
VAL_IS_TEXT_PTR,
|
||
(FLMUINT)((FLMBYTE *)(&TempBuf [0])), 0,
|
||
0, VIEW_INVALID_FILE_OFFSET, 0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
}
|
||
|
||
/* Output the block type */
|
||
|
||
FormatBlkType( TempBuf, BH_GET_TYPE( BlkPtr));
|
||
if (BH_IS_ROOT_BLK( BlkPtr))
|
||
f_strcpy( (char *)&TempBuf [f_strlen( (const char *)TempBuf)], " (Root)");
|
||
if (BH_GET_TYPE( BlkPtr) != (FLMBYTE) BlkExp->Type)
|
||
{
|
||
f_strcpy( (char *)&TempBuf [f_strlen( (const char *)TempBuf)], ", Expecting ");
|
||
FormatBlkType( &TempBuf [f_strlen( (const char *)TempBuf)], BlkExp->Type);
|
||
}
|
||
if (!ViewAddMenuItem( LBL_BLOCK_TYPE, LabelWidth,
|
||
VAL_IS_TEXT_PTR,
|
||
(FLMUINT)((FLMBYTE *)(&TempBuf [0])), 0,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr) + BH_TYPE, 0,
|
||
MOD_FLMBYTE | MOD_HEX,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
|
||
/* Output the level in the B-TREE */
|
||
|
||
if (!OutBlkHdrExpNum( Col, &Row, bc, fc, mbc, mfc, sbc, sfc,
|
||
LabelWidth, LBL_B_TREE_LEVEL,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr) + BH_LEVEL,
|
||
&BlkPtr [BH_LEVEL],
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
MOD_FLMBYTE | MOD_DECIMAL,
|
||
(FLMUINT)BlkExp->Level, (FLMUINT)0xFF, 0))
|
||
return( 0);
|
||
|
||
/* Output the end of the block */
|
||
|
||
EndOfBlock = FB2UW( &BlkPtr [BH_BLK_END]);
|
||
if (!ViewAddMenuItem( LBL_BLOCK_END, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)EndOfBlock, 0,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr) + BH_BLK_END, 0,
|
||
MOD_FLMUINT | MOD_DECIMAL,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
|
||
/* Output the percent full */
|
||
|
||
BytesUsed = EndOfBlock - BH_OVHD;
|
||
if ((!BytesUsed) || (EndOfBlock < BH_OVHD))
|
||
PercentFull = 0;
|
||
else if (EndOfBlock > gv_ViewHdrInfo.FileHdr.uiBlockSize)
|
||
PercentFull = 100;
|
||
else
|
||
PercentFull = ((FLMUINT)(BytesUsed) * (FLMUINT)(100)) /
|
||
(FLMUINT)(gv_ViewHdrInfo.FileHdr.uiBlockSize - BH_OVHD);
|
||
if (!ViewAddMenuItem( LBL_PERCENT_FULL, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)PercentFull, 0,
|
||
0, VIEW_INVALID_FILE_OFFSET, 0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
|
||
/* Output the block transaction ID */
|
||
|
||
if (!ViewAddMenuItem( LBL_BLOCK_TRANS_ID, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
FB2UD( &BlkPtr [BH_TRANS_ID]), 0,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr) + BH_TRANS_ID, 0,
|
||
MOD_FLMUINT | MOD_DECIMAL,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
|
||
/* Output the encryption flag */
|
||
|
||
if (!ViewAddMenuItem( LBL_BLOCK_ENCRYPTED, LabelWidth,
|
||
VAL_IS_LABEL_INDEX,
|
||
(BlkPtr [BH_ENCRYPTED])
|
||
? (FLMUINT)LBL_YES
|
||
: (FLMUINT)LBL_NO, 0,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr) + BH_ENCRYPTED, 0,
|
||
MOD_DISABLED | MOD_FLMBYTE,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
|
||
/* Output the old block image address */
|
||
|
||
BlkAddress = FB2UD( &BlkPtr [BH_PREV_BLK_ADDR]);
|
||
if ((BlkAddress == BT_END) || (BlkAddress == 0) ||
|
||
(FB2UD( &BlkPtr [BH_TRANS_ID]) <=
|
||
gv_ViewHdrInfo.LogHdr.uiCurrTransID))
|
||
Option = 0;
|
||
else
|
||
Option = PREV_BLOCK_IMAGE_OPTION;
|
||
if (!ViewAddMenuItem( LBL_OLD_BLOCK_IMAGE_ADDRESS, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
|
||
BlkAddress, 0,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr) + BH_PREV_BLK_ADDR, 0,
|
||
MOD_FLMUINT | MOD_HEX,
|
||
Col, Row++, Option,
|
||
!Option ? bc : mbc,
|
||
!Option ? fc : mfc,
|
||
!Option ? bc : sbc,
|
||
!Option ? fc : sfc))
|
||
return( 0);
|
||
|
||
/* Output the old block image transaction ID */
|
||
|
||
if (!ViewAddMenuItem( LBL_OLD_BLOCK_IMAGE_TRANS_ID, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
FB2UD( &BlkPtr [BH_PREV_TRANS_ID]), 0,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr) + BH_PREV_TRANS_ID, 0,
|
||
MOD_FLMUINT | MOD_DECIMAL,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
|
||
/* Output the low byte of the block checksum */
|
||
|
||
bySaveChar = (FLMBYTE)(ui16BlkChkSum & 0x00FF);
|
||
if (!OutBlkHdrExpNum( Col, &Row, bc, fc, mbc, mfc, sbc, sfc,
|
||
LabelWidth, LBL_BLOCK_CHECKSUM_LOW,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr) + BH_CHECKSUM_LOW,
|
||
&bySaveChar,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
MOD_FLMBYTE | MOD_DECIMAL,
|
||
(FLMUINT)((ui16BlkChkSum)
|
||
? (FLMUINT)(ui16CalcChkSum & 0x00FF)
|
||
: (FLMUINT)0), 0, 0))
|
||
{
|
||
BlkPtr [BH_CHECKSUM_LOW] = bySaveChar;
|
||
return( 0);
|
||
}
|
||
|
||
/* Output the high byte of the block checksum */
|
||
|
||
bySaveChar = (FLMBYTE)(ui16BlkChkSum >> 8);
|
||
if (!OutBlkHdrExpNum( Col, &Row, bc, fc, mbc, mfc, sbc, sfc,
|
||
LabelWidth, LBL_BLOCK_CHECKSUM_HIGH,
|
||
FSGetFileNumber( BlkExp->BlkAddr),
|
||
FSGetFileOffset( BlkExp->BlkAddr) + BH_CHECKSUM_HIGH,
|
||
&bySaveChar,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
MOD_FLMBYTE | MOD_DECIMAL,
|
||
(FLMUINT)((ui16BlkChkSum)
|
||
? (FLMUINT)(ui16CalcChkSum >> 8)
|
||
: (FLMUINT)0), 0, 0))
|
||
return( 0);
|
||
|
||
/* Output the flags which indicate the state of the block */
|
||
|
||
if (!OutputStatus( Col, &Row, bc, fc, LabelWidth, LBL_BLOCK_STATUS,
|
||
BlkStatus))
|
||
return( 0);
|
||
|
||
*RowRV = Row + 1;
|
||
return( 1);
|
||
}
|
||
|
||
/***************************************************************************
|
||
Name: ViewAvailBlk
|
||
Desc: This routine displays a block in the AVAIL list.
|
||
*****************************************************************************/
|
||
FLMINT ViewAvailBlk(
|
||
FLMUINT ReadAddress,
|
||
FLMUINT BlkAddress,
|
||
FLMBYTE ** BlkPtrRV,
|
||
BLK_EXP_p BlkExp
|
||
)
|
||
{
|
||
FLMINT iRc = 0;
|
||
FLMUINT Row;
|
||
FLMUINT Col;
|
||
FLMBYTE * BlkPtr;
|
||
FLMBYTE BlkStatus [NUM_STATUS_BYTES];
|
||
STATE_INFO StateInfo;
|
||
FLMBOOL bStateInitialized = FALSE;
|
||
BLOCK_INFO BlockInfo;
|
||
eCorruptionType eCorruptionCode;
|
||
FLMUINT16 ui16CalcChkSum;
|
||
FLMUINT16 ui16BlkChkSum;
|
||
FLMUINT uiBytesRead;
|
||
|
||
/* Read the block into memory */
|
||
|
||
if (!ViewBlkRead( ReadAddress, BlkPtrRV,
|
||
gv_ViewHdrInfo.FileHdr.uiBlockSize,
|
||
&ui16CalcChkSum, &ui16BlkChkSum, &uiBytesRead, TRUE,
|
||
NULL, FALSE, NULL))
|
||
{
|
||
goto Exit;
|
||
}
|
||
BlkPtr = *BlkPtrRV;
|
||
|
||
if (!ViewMenuInit( "AVAIL Block"))
|
||
{
|
||
goto Exit;
|
||
}
|
||
|
||
/* Output the block header first */
|
||
|
||
Row = 0;
|
||
Col = 5;
|
||
BlkExp->Type = BHT_FREE;
|
||
BlkExp->LfNum = 0;
|
||
BlkExp->BlkAddr = BlkAddress;
|
||
BlkExp->Level = 0xFF;
|
||
|
||
/* Setup the STATE variable for processing through the block */
|
||
|
||
InitStatusBits( BlkStatus);
|
||
flmInitReadState( &StateInfo, &bStateInitialized,
|
||
gv_ViewHdrInfo.FileHdr.uiVersionNum,
|
||
(gv_bViewDbInitialized)
|
||
? (FDB *)gv_hViewDb
|
||
: (FDB *)NULL, NULL, 0, BHT_FREE, NULL);
|
||
StateInfo.uiBlkAddress = BlkAddress;
|
||
StateInfo.pBlk = BlkPtr;
|
||
|
||
if ((eCorruptionCode = flmVerifyBlockHeader( &StateInfo, &BlockInfo,
|
||
gv_ViewHdrInfo.FileHdr.uiBlockSize,
|
||
BlkExp->NextAddr,
|
||
0, (FLMBOOL)(StateInfo.pDb != NULL
|
||
? TRUE
|
||
: FALSE), TRUE)) != FLM_NO_CORRUPTION)
|
||
SetStatusBit( BlkStatus, eCorruptionCode);
|
||
|
||
if (!ViewOutBlkHdr( Col, &Row, BlkPtr, BlkExp, BlkStatus,
|
||
ui16CalcChkSum, ui16BlkChkSum))
|
||
{
|
||
goto Exit;
|
||
}
|
||
iRc = 1;
|
||
Exit:
|
||
if (bStateInitialized && StateInfo.pRecord)
|
||
{
|
||
StateInfo.pRecord->Release();
|
||
StateInfo.pRecord = NULL;
|
||
}
|
||
return( iRc);
|
||
}
|
||
|
||
/***************************************************************************
|
||
Name: OutputHexValue
|
||
Desc: This routine outputs a stream of FLMBYTEs in hex format. This
|
||
routine is used to output key values and records within an
|
||
element.
|
||
*****************************************************************************/
|
||
FSTATIC FLMINT OutputHexValue(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
eColorType bc,
|
||
eColorType fc,
|
||
FLMINT iLabelIndex,
|
||
FLMUINT FileNumber,
|
||
FLMUINT FileOffset,
|
||
FLMBYTE * ValPtr,
|
||
FLMUINT ValLen,
|
||
FLMUINT CopyVal,
|
||
FLMUINT uiModFlag)
|
||
{
|
||
FLMUINT Row = *RowRV;
|
||
FLMUINT BytesPerLine = MAX_HORIZ_SIZE( Col + 3);
|
||
FLMUINT BytesProcessed = 0;
|
||
FLMUINT NumBytes;
|
||
|
||
if (!ValLen)
|
||
{
|
||
return( 1);
|
||
}
|
||
|
||
if (!ViewAddMenuItem( iLabelIndex, 0,
|
||
VAL_IS_EMPTY, 0, 0,
|
||
FileNumber, FileOffset, 0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
Col += 2;
|
||
while( BytesProcessed < ValLen)
|
||
{
|
||
if ((NumBytes = ValLen - BytesProcessed) > BytesPerLine)
|
||
NumBytes = BytesPerLine;
|
||
|
||
/* Output the line */
|
||
|
||
if (!ViewAddMenuItem( -1, 0,
|
||
(FLMBYTE)((CopyVal)
|
||
? (FLMBYTE)VAL_IS_BINARY
|
||
: (FLMBYTE)VAL_IS_BINARY_PTR),
|
||
(FLMUINT)ValPtr, NumBytes,
|
||
FileNumber, FileOffset, NumBytes, uiModFlag,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
return( 0);
|
||
FileOffset += (FLMUINT)NumBytes;
|
||
BytesProcessed += NumBytes;
|
||
ValPtr += NumBytes;
|
||
}
|
||
*RowRV = Row;
|
||
return( 1);
|
||
}
|
||
|
||
/***************************************************************************
|
||
Name: OutputLeafElements
|
||
Desc: This routine outputs the elements in a LEAF block.
|
||
*****************************************************************************/
|
||
FSTATIC FLMINT OutputLeafElements(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
FLMBYTE * BlkPtr,
|
||
BLK_EXP_p BlkExp,
|
||
FLMBYTE * BlkStatusRV,
|
||
FLMUINT StatusOnlyFlag,
|
||
FLMBOOL bEncrypted
|
||
)
|
||
{
|
||
FLMINT iRc = 0;
|
||
FLMUINT LabelWidth = 30;
|
||
eColorType bc = FLM_BLACK;
|
||
eColorType fc = FLM_LIGHTGRAY;
|
||
FLMUINT Row = *RowRV;
|
||
FLMUINT ElementCount = 0;
|
||
eCorruptionType eCorruptionCode;
|
||
FLMUINT LfType = LF_INVALID;
|
||
FLMBYTE ElmStatus [NUM_STATUS_BYTES];
|
||
STATE_INFO StateInfo;
|
||
FLMBOOL bStateInitialized = FALSE;
|
||
BLOCK_INFO BlockInfo;
|
||
FLMBYTE KeyBuffer [MAX_KEY_SIZ];
|
||
LFILE * pLFile = NULL;
|
||
LF_HDR LogicalFile;
|
||
LF_STATS LfStats;
|
||
LF_HDR * pLogicalFile = NULL;
|
||
|
||
if (BlkExp->LfNum == 0)
|
||
BlkExp->LfNum = FB2UW( &BlkPtr [BH_LOG_FILE_NUM]);
|
||
|
||
/* Setup the STATE variable for processing through the block */
|
||
|
||
ViewGetDictInfo();
|
||
if (gv_bViewHaveDictInfo)
|
||
{
|
||
if ((RC_OK( fdictGetIndex(
|
||
((FDB *)gv_hViewDb)->pDict,
|
||
((FDB *)gv_hViewDb)->pFile->bInLimitedMode,
|
||
BlkExp->LfNum, &pLFile, NULL))) ||
|
||
(RC_OK( fdictGetContainer(
|
||
((FDB *)gv_hViewDb)->pDict,
|
||
BlkExp->LfNum, &pLFile))))
|
||
{
|
||
f_memset( &LogicalFile, 0, sizeof( LF_HDR));
|
||
f_memset( &LfStats, 0, sizeof( LF_STATS));
|
||
pLogicalFile = &LogicalFile;
|
||
pLogicalFile->pLfStats = &LfStats;
|
||
LogicalFile.pLFile = pLFile;
|
||
if (pLFile->uiLfType == LF_INDEX)
|
||
{
|
||
if (RC_BAD( fdictGetIndex(
|
||
((FDB *)gv_hViewDb)->pDict,
|
||
((FDB *)gv_hViewDb)->pFile->bInLimitedMode,
|
||
pLFile->uiLfNum, &LogicalFile.pLFile,
|
||
&LogicalFile.pIxd)))
|
||
{
|
||
pLogicalFile = NULL;
|
||
}
|
||
LogicalFile.pIfd = LogicalFile.pIxd->pFirstIfd;
|
||
}
|
||
}
|
||
}
|
||
LfType = (pLogicalFile) ? pLogicalFile->pLFile->uiLfType : LF_INVALID;
|
||
|
||
flmInitReadState( &StateInfo, &bStateInitialized,
|
||
gv_ViewHdrInfo.FileHdr.uiVersionNum,
|
||
(gv_bViewDbInitialized)
|
||
? (FDB *)gv_hViewDb
|
||
: (FDB *)NULL, pLogicalFile, 0,
|
||
BHT_LEAF, KeyBuffer);
|
||
StateInfo.uiBlkAddress = BlkExp->BlkAddr;
|
||
StateInfo.pBlk = BlkPtr;
|
||
|
||
if ((eCorruptionCode = flmVerifyBlockHeader( &StateInfo, &BlockInfo,
|
||
gv_ViewHdrInfo.FileHdr.uiBlockSize,
|
||
BlkExp->NextAddr,
|
||
BlkExp->PrevAddr,
|
||
(FLMBOOL)(StateInfo.pDb != NULL
|
||
? TRUE
|
||
: FALSE), TRUE)) != FLM_NO_CORRUPTION)
|
||
SetStatusBit( BlkStatusRV, eCorruptionCode);
|
||
|
||
if (bEncrypted)
|
||
{
|
||
if (!StatusOnlyFlag)
|
||
{
|
||
FLMUINT uiEncSize = getEncryptSize( StateInfo.pBlk) - BH_OVHD;
|
||
|
||
if (uiEncSize)
|
||
{
|
||
|
||
// Output the rest of the block as HEX - cannot be parsed through
|
||
// when it is encrypted
|
||
|
||
OutputHexValue( Col, &Row, bc, fc, LBL_ENC_DATA,
|
||
FSGetFileNumber(StateInfo.uiBlkAddress),
|
||
FSGetFileOffset(StateInfo.uiBlkAddress) + BH_OVHD,
|
||
&StateInfo.pBlk [BH_OVHD], uiEncSize, FALSE, MOD_BINARY_ENC);
|
||
}
|
||
}
|
||
iRc = 1;
|
||
goto Exit;
|
||
}
|
||
|
||
/* Read through the elements in the block */
|
||
|
||
while( StateInfo.uiElmOffset < StateInfo.uiEndOfBlock)
|
||
{
|
||
ElementCount++;
|
||
InitStatusBits( ElmStatus);
|
||
|
||
if ((eCorruptionCode = flmVerifyElement( &StateInfo, FLM_CHK_FIELDS)) != FLM_NO_CORRUPTION)
|
||
SetStatusBit( ElmStatus, eCorruptionCode);
|
||
else if (LfType == LF_INDEX)
|
||
{
|
||
if (StateInfo.uiCurKeyLen)
|
||
{
|
||
if( RC_BAD( flmVerifyIXRefs( &StateInfo, NULL, 0,
|
||
&eCorruptionCode)) || eCorruptionCode != FLM_NO_CORRUPTION)
|
||
{
|
||
SetStatusBit( ElmStatus, eCorruptionCode);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Output the element */
|
||
|
||
if (!StatusOnlyFlag)
|
||
{
|
||
Row++;
|
||
|
||
/* Output the element number */
|
||
|
||
if (!ViewAddMenuItem( LBL_ELEMENT_NUMBER, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)ElementCount, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) + StateInfo.uiElmOffset,
|
||
0, MOD_DISABLED,
|
||
Col, Row++, 0,
|
||
FLM_GREEN, FLM_WHITE,
|
||
FLM_GREEN, FLM_WHITE))
|
||
goto Exit;
|
||
|
||
/* Remember this item if we are searching */
|
||
|
||
if ((gv_bViewSearching) &&
|
||
(flmCompareKeys( StateInfo.pCurKey, StateInfo.uiCurKeyLen,
|
||
gv_ucViewSearchKey,
|
||
gv_uiViewSearchKeyLen) >= 0) &&
|
||
(gv_pViewSearchItem == NULL))
|
||
{
|
||
gv_pViewSearchItem = gv_pViewMenuLastItem;
|
||
}
|
||
|
||
/* Output the element offset within the block */
|
||
|
||
if (!ViewAddMenuItem( LBL_ELEMENT_OFFSET, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo.uiElmOffset, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset,
|
||
0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
/* Output the element length */
|
||
|
||
if (!ViewAddMenuItem( LBL_ELEMENT_LENGTH, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo.uiElmLen, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset,
|
||
0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
/* Display the first element flag */
|
||
|
||
if (!ViewAddMenuItem( LBL_FIRST_ELEMENT_FLAG, LabelWidth,
|
||
VAL_IS_LABEL_INDEX,
|
||
(BBE_IS_FIRST( StateInfo.pElm))
|
||
? (FLMUINT)LBL_YES
|
||
: (FLMUINT)LBL_NO, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) + StateInfo.uiElmOffset,
|
||
0x80, MOD_BITS | MOD_DECIMAL,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
/* Display the last element flag */
|
||
|
||
if (!ViewAddMenuItem( LBL_LAST_ELEMENT_FLAG, LabelWidth,
|
||
VAL_IS_LABEL_INDEX,
|
||
(BBE_IS_LAST( StateInfo.pElm))
|
||
? (FLMUINT)LBL_YES
|
||
: (FLMUINT)LBL_NO, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset, 0x40,
|
||
MOD_BITS | MOD_DECIMAL,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
if (eCorruptionCode != FLM_NO_CORRUPTION)
|
||
{
|
||
if ((LfType != LF_INDEX) &&
|
||
(LfType != LF_INVALID) &&
|
||
(StateInfo.uiCurKeyLen) &&
|
||
(StateInfo.uiElmDrn != DRN_LAST_MARKER))
|
||
{
|
||
FLMUINT r = 0;
|
||
STATE_INFO DummyState;
|
||
FLMBYTE TempKeyBuffer [MAX_KEY_SIZ];
|
||
|
||
f_memcpy( &DummyState, &StateInfo, sizeof( STATE_INFO));
|
||
f_memcpy( TempKeyBuffer, KeyBuffer, MAX_KEY_SIZ);
|
||
DummyState.pCurKey = &TempKeyBuffer [0];
|
||
if (!OutputElmRecord( Col, &r, bc, fc, LabelWidth,
|
||
&DummyState, ElmStatus, TRUE))
|
||
goto Exit;
|
||
}
|
||
if (!OutputStatus( Col, &Row, bc, fc, LabelWidth,
|
||
LBL_ELEMENT_STATUS, ElmStatus))
|
||
goto Exit;
|
||
}
|
||
|
||
/* Display the Previous Key Count */
|
||
|
||
if (!ViewAddMenuItem( LBL_PREVIOUS_KEY_CONT_LEN, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo.uiElmPKCLen, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) + StateInfo.uiElmOffset,
|
||
0x0F, MOD_BITS | MOD_DECIMAL,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
/* Output the previous key portion, if any */
|
||
|
||
if (!OutputHexValue( Col, &Row, bc, fc,
|
||
LBL_PREV_ELEMENT_KEY,
|
||
0, VIEW_INVALID_FILE_OFFSET,
|
||
StateInfo.pCurKey, StateInfo.uiElmPKCLen,
|
||
TRUE, MOD_BINARY))
|
||
goto Exit;
|
||
|
||
/* Display the key length */
|
||
|
||
if (!ViewAddMenuItem( LBL_KEY_LENGTH, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo.uiElmKeyLen, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset, 0,
|
||
MOD_KEY_LEN | MOD_DECIMAL,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
/* Output the current key portion, if any */
|
||
|
||
if (!OutputHexValue( Col, &Row, bc, fc, LBL_ELEMENT_KEY,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset + BBE_KEY,
|
||
StateInfo.pElmKey, StateInfo.uiElmKeyLen,
|
||
FALSE, MOD_BINARY))
|
||
goto Exit;
|
||
if ((LfType != LF_INDEX) && (LfType != LF_INVALID))
|
||
{
|
||
if (StateInfo.uiElmDrn != DRN_LAST_MARKER)
|
||
{
|
||
if (!ViewAddMenuItem( LBL_ELEMENT_DRN, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL_HEX,
|
||
StateInfo.uiElmDrn, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset + BBE_KEY,
|
||
StateInfo.uiElmKeyLen,
|
||
MOD_DISABLED | MOD_BINARY,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
}
|
||
|
||
/* Display the Next DRN marker if there is one */
|
||
|
||
if (StateInfo.uiElmDrn == DRN_LAST_MARKER)
|
||
{
|
||
if (!ViewAddMenuItem( LBL_NEXT_DRN_MARKER, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL_HEX,
|
||
StateInfo.uiLastElmDrn, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset + BBE_KEY+4,
|
||
StateInfo.uiElmKeyLen,
|
||
MOD_DISABLED | MOD_BINARY,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
}
|
||
}
|
||
|
||
/* Display the record length */
|
||
|
||
if (!ViewAddMenuItem( LBL_RECORD_LENGTH, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo.uiElmRecLen, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset + BBE_RL,
|
||
0,
|
||
MOD_FLMBYTE | MOD_DECIMAL,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
if ((LfType == LF_INDEX) || (LfType == LF_INVALID))
|
||
{
|
||
|
||
/* Output the record portion */
|
||
|
||
if (!OutputHexValue( Col, &Row, bc, fc, LBL_RECORD,
|
||
FSGetFileNumber(StateInfo.uiBlkAddress),
|
||
FSGetFileOffset(StateInfo.uiBlkAddress) +
|
||
(FLMUINT)(StateInfo.pElmRec - StateInfo.pBlk),
|
||
StateInfo.pElmRec, StateInfo.uiElmRecLen,
|
||
FALSE, MOD_BINARY))
|
||
goto Exit;
|
||
}
|
||
}
|
||
if ((LfType != LF_INDEX) &&
|
||
(LfType != LF_INVALID) &&
|
||
(StateInfo.uiCurKeyLen) &&
|
||
( StateInfo.uiElmDrn != DRN_LAST_MARKER))
|
||
{
|
||
if (!OutputElmRecord( Col, &Row, bc, fc, LabelWidth,
|
||
&StateInfo, ElmStatus, StatusOnlyFlag))
|
||
goto Exit;
|
||
}
|
||
|
||
/* Go to the next element */
|
||
|
||
StateInfo.uiElmOffset += StateInfo.uiElmLen;
|
||
OrStatusBits( BlkStatusRV, ElmStatus);
|
||
}
|
||
|
||
/* Verify that we ended exactly on the end of the block */
|
||
|
||
if ((!TestStatusBit( BlkStatusRV, FLM_BAD_BLK_HDR_BLK_END)) &&
|
||
(StateInfo.uiElmOffset > StateInfo.uiEndOfBlock))
|
||
SetStatusBit( BlkStatusRV, FLM_BAD_ELM_END);
|
||
|
||
if (!StatusOnlyFlag)
|
||
{
|
||
*RowRV = Row;
|
||
|
||
/* If we were searching and did not find a key, set it on the */
|
||
/* last key found */
|
||
|
||
if ((gv_bViewSearching) && (gv_pViewSearchItem == NULL))
|
||
{
|
||
gv_pViewSearchItem = gv_pViewMenuLastItem;
|
||
while ((gv_pViewSearchItem != NULL) &&
|
||
(gv_pViewSearchItem->iLabelIndex != LBL_ELEMENT_NUMBER))
|
||
gv_pViewSearchItem = gv_pViewSearchItem->PrevItem;
|
||
}
|
||
}
|
||
iRc = 1;
|
||
Exit:
|
||
if (bStateInitialized && StateInfo.pRecord)
|
||
{
|
||
StateInfo.pRecord->Release();
|
||
StateInfo.pRecord = NULL;
|
||
}
|
||
return( iRc);
|
||
}
|
||
|
||
/***************************************************************************
|
||
Name: ViewLeafBlk
|
||
Desc: This routine outputs a LEAF block, including the block header.
|
||
*****************************************************************************/
|
||
FLMINT ViewLeafBlk(
|
||
FLMUINT ReadAddress,
|
||
FLMUINT BlkAddress,
|
||
FLMBYTE ** BlkPtrRV,
|
||
BLK_EXP_p BlkExp
|
||
)
|
||
{
|
||
FLMUINT Row;
|
||
FLMUINT Col;
|
||
FLMBYTE * BlkPtr;
|
||
FLMBYTE BlkStatus [NUM_STATUS_BYTES];
|
||
FLMUINT16 ui16CalcChkSum;
|
||
FLMUINT16 ui16BlkChkSum;
|
||
FLMUINT uiBytesRead;
|
||
FLMBOOL bEncrypted;
|
||
|
||
InitStatusBits( BlkStatus);
|
||
|
||
/* Read the block into memory */
|
||
|
||
if (!ViewBlkRead( ReadAddress, BlkPtrRV,
|
||
gv_ViewHdrInfo.FileHdr.uiBlockSize,
|
||
&ui16CalcChkSum, &ui16BlkChkSum,
|
||
&uiBytesRead, TRUE, NULL, TRUE, &bEncrypted))
|
||
return( 0);
|
||
BlkPtr = *BlkPtrRV;
|
||
|
||
if (!ViewMenuInit( "LEAF Block"))
|
||
return( 0);
|
||
|
||
/* Output the block header first */
|
||
|
||
Row = 0;
|
||
Col = 5;
|
||
BlkExp->Type = BHT_LEAF;
|
||
BlkExp->BlkAddr = BlkAddress;
|
||
BlkExp->Level = 0;
|
||
|
||
OutputLeafElements( Col, &Row, BlkPtr, BlkExp, BlkStatus, TRUE,
|
||
bEncrypted);
|
||
if (!ViewOutBlkHdr( Col, &Row, BlkPtr, BlkExp, BlkStatus,
|
||
ui16CalcChkSum, ui16BlkChkSum))
|
||
return( 0);
|
||
|
||
/* Now output the leaf data */
|
||
|
||
if (!OutputLeafElements( Col, &Row, BlkPtr, BlkExp,
|
||
BlkStatus, FALSE, bEncrypted))
|
||
return( 0);
|
||
return( 1);
|
||
}
|
||
|
||
/***************************************************************************
|
||
Name: OutputNonLeafElements
|
||
Desc: This routine outputs the elements of a NON-LEAF block.
|
||
*****************************************************************************/
|
||
FSTATIC FLMINT OutputNonLeafElements(
|
||
FLMUINT Col,
|
||
FLMUINT * RowRV,
|
||
FLMBYTE * BlkPtr,
|
||
BLK_EXP_p BlkExp,
|
||
FLMBYTE * BlkStatusRV,
|
||
FLMUINT StatusOnlyFlag,
|
||
FLMBOOL bEncrypted
|
||
)
|
||
{
|
||
FLMINT iRc = 0;
|
||
FLMUINT LabelWidth = 30;
|
||
eColorType bc = FLM_BLACK;
|
||
eColorType fc = FLM_LIGHTGRAY;
|
||
eColorType mbc = FLM_BLACK;
|
||
eColorType mfc = FLM_WHITE;
|
||
eColorType sbc = FLM_BLUE;
|
||
eColorType sfc = FLM_WHITE;
|
||
FLMUINT Row = *RowRV;
|
||
FLMUINT ElementCount = 0;
|
||
FLMBYTE * TempAddrPtr;
|
||
FLMUINT TempAddress;
|
||
eCorruptionType eCorruptionCode;
|
||
FLMUINT Option;
|
||
FLMUINT LfType;
|
||
FLMUINT uiBlkType = BlkExp->Type;
|
||
FLMBYTE ElmStatus [NUM_STATUS_BYTES];
|
||
STATE_INFO StateInfo;
|
||
FLMBOOL bStateInitialized = FALSE;
|
||
BLOCK_INFO BlockInfo;
|
||
FLMBYTE KeyBuffer [MAX_KEY_SIZ];
|
||
LF_HDR LogicalFile;
|
||
LF_HDR * pLogicalFile = NULL;
|
||
LFILE * pLFile = NULL;
|
||
FLMUINT uiFixedDrn = 0;
|
||
|
||
if (BlkExp->LfNum == 0)
|
||
BlkExp->LfNum = FB2UW( &BlkPtr [BH_LOG_FILE_NUM]);
|
||
|
||
/* Setup the STATE variable for processing through the block */
|
||
|
||
ViewGetDictInfo();
|
||
if (gv_bViewHaveDictInfo)
|
||
{
|
||
if ((RC_OK( fdictGetIndex(
|
||
((FDB *)gv_hViewDb)->pDict,
|
||
((FDB *)gv_hViewDb)->pFile->bInLimitedMode,
|
||
BlkExp->LfNum, &pLFile, NULL))) ||
|
||
(RC_OK( fdictGetContainer(
|
||
((FDB *)gv_hViewDb)->pDict,
|
||
BlkExp->LfNum, &pLFile))))
|
||
{
|
||
f_memset( &LogicalFile, 0, sizeof( LF_HDR));
|
||
pLogicalFile = &LogicalFile;
|
||
LogicalFile.pLFile = pLFile;
|
||
if (pLFile->uiLfType == LF_INDEX)
|
||
{
|
||
if (RC_BAD( fdictGetIndex(
|
||
((FDB *)gv_hViewDb)->pDict,
|
||
((FDB *)gv_hViewDb)->pFile->bInLimitedMode,
|
||
pLFile->uiLfNum, &LogicalFile.pLFile,
|
||
&LogicalFile.pIxd)))
|
||
{
|
||
pLogicalFile = NULL;
|
||
}
|
||
LogicalFile.pIfd = LogicalFile.pIxd->pFirstIfd;
|
||
}
|
||
}
|
||
}
|
||
LfType = (pLogicalFile) ? pLogicalFile->pLFile->uiLfType : LF_INVALID;
|
||
|
||
if (uiBlkType != BHT_NON_LEAF &&
|
||
uiBlkType != BHT_NON_LEAF_COUNTS &&
|
||
uiBlkType != BHT_NON_LEAF_DATA)
|
||
{
|
||
if (pLogicalFile)
|
||
{
|
||
if (LfType == LF_INDEX)
|
||
{
|
||
if (pLogicalFile->pIxd &&
|
||
(pLogicalFile->pIxd->uiFlags & IXD_POSITIONING))
|
||
{
|
||
uiBlkType = BHT_NON_LEAF_COUNTS;
|
||
}
|
||
else
|
||
{
|
||
uiBlkType = BHT_NON_LEAF;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
uiBlkType = BHT_NON_LEAF_DATA;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
uiBlkType = BHT_NON_LEAF;
|
||
}
|
||
}
|
||
|
||
flmInitReadState( &StateInfo, &bStateInitialized,
|
||
gv_ViewHdrInfo.FileHdr.uiVersionNum,
|
||
(gv_bViewDbInitialized)
|
||
? (FDB *)gv_hViewDb
|
||
: (FDB *)NULL, pLogicalFile, BlkExp->Level,
|
||
uiBlkType, KeyBuffer);
|
||
StateInfo.uiBlkAddress = BlkExp->BlkAddr;
|
||
StateInfo.pBlk = BlkPtr;
|
||
|
||
if ((eCorruptionCode = flmVerifyBlockHeader( &StateInfo, &BlockInfo,
|
||
gv_ViewHdrInfo.FileHdr.uiBlockSize,
|
||
BlkExp->NextAddr,
|
||
BlkExp->PrevAddr,
|
||
(FLMBOOL)(StateInfo.pDb != NULL
|
||
? TRUE
|
||
: FALSE), TRUE)) != FLM_NO_CORRUPTION)
|
||
SetStatusBit( BlkStatusRV, eCorruptionCode);
|
||
|
||
if (bEncrypted)
|
||
{
|
||
if (!StatusOnlyFlag)
|
||
{
|
||
FLMUINT uiEncSize = getEncryptSize( StateInfo.pBlk) - BH_OVHD;
|
||
|
||
if (uiEncSize)
|
||
{
|
||
|
||
// Output the rest of the block as HEX - cannot be parsed through
|
||
// when it is encrypted
|
||
|
||
OutputHexValue( Col, &Row, bc, fc, LBL_ENC_DATA,
|
||
FSGetFileNumber(StateInfo.uiBlkAddress),
|
||
FSGetFileOffset(StateInfo.uiBlkAddress) + BH_OVHD,
|
||
&StateInfo.pBlk [BH_OVHD], uiEncSize, FALSE, MOD_BINARY_ENC);
|
||
}
|
||
}
|
||
iRc = 1;
|
||
goto Exit;
|
||
}
|
||
|
||
/* Output each element in the block */
|
||
|
||
while (StateInfo.uiElmOffset < StateInfo.uiEndOfBlock)
|
||
{
|
||
InitStatusBits( ElmStatus);
|
||
ElementCount++;
|
||
|
||
if ((eCorruptionCode = flmVerifyElement( &StateInfo, FLM_CHK_FIELDS)) != FLM_NO_CORRUPTION)
|
||
SetStatusBit( ElmStatus, eCorruptionCode);
|
||
|
||
if (!StatusOnlyFlag)
|
||
{
|
||
Row++;
|
||
|
||
/* Output the element number */
|
||
|
||
if (!ViewAddMenuItem( LBL_ELEMENT_NUMBER, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)ElementCount, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset,
|
||
0, MOD_DISABLED,
|
||
Col, Row++, 0,
|
||
FLM_GREEN, FLM_WHITE,
|
||
FLM_GREEN, FLM_WHITE))
|
||
goto Exit;
|
||
|
||
/* Output the element offset within the block */
|
||
|
||
if (!ViewAddMenuItem( LBL_ELEMENT_OFFSET, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo.uiElmOffset, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset,
|
||
0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
/* Output the element length */
|
||
|
||
if (!ViewAddMenuItem( LBL_ELEMENT_LENGTH, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo.uiElmLen, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset,
|
||
0, MOD_DISABLED,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
/* Display the domain flag */
|
||
|
||
if (!ViewAddMenuItem( LBL_DOMAIN_PRESENT_FLAG, LabelWidth,
|
||
VAL_IS_LABEL_INDEX,
|
||
(BNE_IS_DOMAIN( StateInfo.pElm))
|
||
? (FLMUINT)LBL_YES
|
||
: (FLMUINT)LBL_NO, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset,
|
||
0x80, MOD_BITS | MOD_DECIMAL,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
/* Display the domain number */
|
||
|
||
if (uiBlkType != BHT_NON_LEAF_DATA && (BNE_IS_DOMAIN( StateInfo.pElm)))
|
||
{
|
||
TempAddrPtr = &StateInfo.pElmKey [StateInfo.uiElmKeyLen];
|
||
TempAddress = ((FLMUINT) (*TempAddrPtr++)) << 16;
|
||
TempAddress |= (FLMUINT) ((*TempAddrPtr++) << 8);
|
||
TempAddress |= (FLMUINT) (*TempAddrPtr);
|
||
TempAddress <<= 8;
|
||
}
|
||
else
|
||
TempAddress = 0;
|
||
if (!ViewAddMenuItem( LBL_DOMAIN_NUMBER, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
|
||
(FLMUINT)TempAddress, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
((FLMUINT)(StateInfo.pElmKey - StateInfo.pBlk) +
|
||
StateInfo.uiElmKeyLen),
|
||
0,
|
||
(FLMBYTE)((TempAddress)
|
||
? (FLMBYTE)MOD_CHILD_BLK
|
||
: (FLMBYTE)MOD_DISABLED),
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
/* Display the child block address */
|
||
|
||
if (uiBlkType == BHT_NON_LEAF_DATA)
|
||
{
|
||
uiFixedDrn = f_bigEndianToUINT32( StateInfo.pElm);
|
||
TempAddrPtr = &StateInfo.pElm [BNE_DATA_CHILD_BLOCK];
|
||
}
|
||
else
|
||
{
|
||
TempAddrPtr = &StateInfo.pElm [BNE_CHILD_BLOCK];
|
||
}
|
||
TempAddress = FB2UD( TempAddrPtr);
|
||
if (TempAddress == BT_END)
|
||
Option = 0;
|
||
else
|
||
Option = BLK_OPTION_CHILD_BLOCK | StateInfo.uiElmOffset;
|
||
if (!ViewAddMenuItem( LBL_CHILD_BLOCK_ADDRESS, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_HEX_DECIMAL,
|
||
(FLMUINT)TempAddress, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset +
|
||
(FLMUINT) (TempAddrPtr - StateInfo.pElm),
|
||
0, MOD_CHILD_BLK,
|
||
Col, Row++, Option,
|
||
!Option ? bc : mbc,
|
||
!Option ? fc : mfc,
|
||
!Option ? bc : sbc,
|
||
!Option ? fc : sfc))
|
||
goto Exit;
|
||
|
||
if (uiBlkType == BHT_NON_LEAF_COUNTS)
|
||
{
|
||
TempAddrPtr = &StateInfo.pElm [BNE_CHILD_COUNT];
|
||
if (!ViewAddMenuItem( LBL_CHILD_REFERENCE_COUNT, LabelWidth,
|
||
VAL_IS_NUMBER,
|
||
(FLMUINT) StateInfo.uiChildCount, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset +
|
||
(FLMUINT) (TempAddrPtr - StateInfo.pElm),
|
||
0, MOD_FLMUINT | MOD_DECIMAL,
|
||
Col, Row++, Option, bc, fc, bc, fc))
|
||
goto Exit;
|
||
}
|
||
|
||
/* Remember this item if we are searching */
|
||
|
||
if ((gv_bViewSearching) &&
|
||
(flmCompareKeys( StateInfo.pCurKey, StateInfo.uiCurKeyLen,
|
||
gv_ucViewSearchKey, gv_uiViewSearchKeyLen) >= 0) &&
|
||
(gv_pViewSearchItem == NULL))
|
||
{
|
||
gv_pViewSearchItem = gv_pViewMenuLastItem;
|
||
}
|
||
|
||
if (eCorruptionCode != FLM_NO_CORRUPTION)
|
||
{
|
||
if (!OutputStatus( Col, &Row, bc, fc, LabelWidth, LBL_ELEMENT_STATUS,
|
||
ElmStatus))
|
||
goto Exit;
|
||
}
|
||
|
||
/* Display the Previous Key Count */
|
||
|
||
if (!ViewAddMenuItem( LBL_PREVIOUS_KEY_CONT_LEN, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo.uiElmPKCLen, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset, 0x0F,
|
||
MOD_BITS | MOD_DECIMAL,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
if (uiBlkType != BHT_NON_LEAF_DATA)
|
||
{
|
||
/* Output the previous key portion, if any */
|
||
|
||
if (!OutputHexValue( Col, &Row, bc, fc,
|
||
LBL_PREV_ELEMENT_KEY,
|
||
0, VIEW_INVALID_FILE_OFFSET,
|
||
StateInfo.pCurKey, StateInfo.uiElmPKCLen,
|
||
TRUE, MOD_BINARY))
|
||
goto Exit;
|
||
|
||
/* Display the key length */
|
||
|
||
if (!ViewAddMenuItem( LBL_KEY_LENGTH, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL,
|
||
(FLMUINT)StateInfo.uiElmKeyLen, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
StateInfo.uiElmOffset, 0,
|
||
MOD_KEY_LEN | MOD_DECIMAL,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
|
||
/* Output the current key portion, if any */
|
||
|
||
if (!OutputHexValue( Col, &Row, bc, fc, LBL_ELEMENT_KEY,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
(FLMUINT)(StateInfo.pElmKey - StateInfo.pBlk),
|
||
StateInfo.pElmKey, StateInfo.uiElmKeyLen,
|
||
FALSE, MOD_BINARY))
|
||
goto Exit;
|
||
}
|
||
|
||
if (((LfType != LF_INDEX) && (LfType != LF_INVALID)) ||
|
||
(uiBlkType == BHT_NON_LEAF_DATA))
|
||
{
|
||
FLMUINT uiDrn = StateInfo.uiElmDrn;
|
||
|
||
if (uiBlkType == BHT_NON_LEAF_DATA)
|
||
{
|
||
uiDrn = uiFixedDrn;
|
||
}
|
||
if (!ViewAddMenuItem( LBL_ELEMENT_DRN, LabelWidth,
|
||
VAL_IS_NUMBER | DISP_DECIMAL_HEX,
|
||
uiFixedDrn, 0,
|
||
FSGetFileNumber( StateInfo.uiBlkAddress),
|
||
FSGetFileOffset( StateInfo.uiBlkAddress) +
|
||
(FLMUINT)(StateInfo.pElmKey - StateInfo.pBlk),
|
||
StateInfo.uiElmKeyLen,
|
||
MOD_DISABLED | MOD_BINARY,
|
||
Col, Row++, 0, bc, fc, bc, fc))
|
||
goto Exit;
|
||
}
|
||
}
|
||
|
||
/* Go to the next element */
|
||
|
||
StateInfo.uiElmOffset += StateInfo.uiElmLen;
|
||
OrStatusBits( BlkStatusRV, ElmStatus);
|
||
}
|
||
|
||
/* Verify that we ended exactly on the end of the block */
|
||
|
||
if ((!TestStatusBit( BlkStatusRV, FLM_BAD_BLK_HDR_BLK_END)) &&
|
||
(StateInfo.uiElmOffset > StateInfo.uiEndOfBlock))
|
||
SetStatusBit( BlkStatusRV, FLM_BAD_ELM_END);
|
||
|
||
if (!StatusOnlyFlag)
|
||
{
|
||
*RowRV = Row;
|
||
|
||
/* If we were searching and did not find a key, set it on the */
|
||
/* last key found */
|
||
|
||
if ((gv_bViewSearching) && (gv_pViewSearchItem == NULL))
|
||
{
|
||
gv_pViewSearchItem = gv_pViewMenuLastItem;
|
||
while ((gv_pViewSearchItem != NULL) &&
|
||
(gv_pViewSearchItem->iLabelIndex != LBL_CHILD_BLOCK_ADDRESS))
|
||
gv_pViewSearchItem = gv_pViewSearchItem->PrevItem;
|
||
}
|
||
}
|
||
iRc = 1;
|
||
Exit:
|
||
if (bStateInitialized && StateInfo.pRecord)
|
||
{
|
||
StateInfo.pRecord->Release();
|
||
StateInfo.pRecord = NULL;
|
||
}
|
||
return( iRc);
|
||
}
|
||
|
||
/***************************************************************************
|
||
Name: ViewNonLeafBlk
|
||
Desc: This routine outputs a NON-LEAF block, including the block header.
|
||
*****************************************************************************/
|
||
FLMINT ViewNonLeafBlk(
|
||
FLMUINT ReadAddress,
|
||
FLMUINT BlkAddress,
|
||
FLMBYTE ** BlkPtrRV,
|
||
BLK_EXP_p BlkExp
|
||
)
|
||
{
|
||
FLMUINT Row;
|
||
FLMUINT Col;
|
||
FLMBYTE * BlkPtr;
|
||
FLMBYTE BlkStatus [NUM_STATUS_BYTES];
|
||
FLMUINT16 ui16CalcChkSum;
|
||
FLMUINT16 ui16BlkChkSum;
|
||
FLMUINT uiBytesRead;
|
||
FLMBOOL bEncrypted;
|
||
|
||
InitStatusBits( BlkStatus);
|
||
|
||
/* Read the block into memory */
|
||
|
||
if (!ViewBlkRead( ReadAddress, BlkPtrRV,
|
||
gv_ViewHdrInfo.FileHdr.uiBlockSize,
|
||
&ui16CalcChkSum, &ui16BlkChkSum,
|
||
&uiBytesRead, TRUE, NULL, TRUE, &bEncrypted))
|
||
return( 0);
|
||
BlkPtr = *BlkPtrRV;
|
||
|
||
if (!ViewMenuInit( "NON-LEAF Block"))
|
||
return( 0);
|
||
|
||
/* Output the block header first */
|
||
|
||
Row = 0;
|
||
Col = 5;
|
||
BlkExp->Type = BH_GET_TYPE( BlkPtr);
|
||
BlkExp->BlkAddr = BlkAddress;
|
||
OutputNonLeafElements( Col, &Row, BlkPtr, BlkExp, BlkStatus, TRUE,
|
||
bEncrypted);
|
||
if (!ViewOutBlkHdr( Col, &Row, BlkPtr, BlkExp, BlkStatus,
|
||
ui16CalcChkSum, ui16BlkChkSum))
|
||
return( 0);
|
||
|
||
/* Now output the non-leaf data */
|
||
|
||
if (!OutputNonLeafElements( Col, &Row, BlkPtr, BlkExp, BlkStatus, FALSE,
|
||
bEncrypted))
|
||
return( 0);
|
||
return( 1);
|
||
}
|
||
|
||
/********************************************************************
|
||
Desc: ?
|
||
*********************************************************************/
|
||
void ViewHexBlock(
|
||
FLMUINT ReadAddress,
|
||
FLMBYTE ** BlkPtrRV,
|
||
FLMBOOL bViewDecrypted,
|
||
FLMUINT uiViewLen
|
||
)
|
||
{
|
||
FLMBYTE * BlkPtr;
|
||
FLMUINT Row = 0;
|
||
FLMUINT Col = 9;
|
||
FLMUINT BytesPerLine = MAX_HORIZ_SIZE( Col);
|
||
FLMUINT BytesProcessed = 0;
|
||
FLMUINT NumBytes;
|
||
FLMUINT FileOffset;
|
||
FLMUINT FileNumber;
|
||
char Title [80];
|
||
FLMUINT16 ui16CalcChkSum;
|
||
FLMUINT16 ui16BlkChkSum;
|
||
FLMUINT uiBytesRead;
|
||
FLMBOOL bIsEncBlock;
|
||
FLMBOOL bEncrypted;
|
||
FLMUINT uiModFlag;
|
||
|
||
FileOffset = FSGetFileOffset( ReadAddress);
|
||
FileNumber = FSGetFileNumber( ReadAddress);
|
||
|
||
if (!ViewBlkRead( ReadAddress, BlkPtrRV, uiViewLen,
|
||
&ui16CalcChkSum, &ui16BlkChkSum,
|
||
&uiBytesRead, TRUE, &bIsEncBlock,
|
||
bViewDecrypted, &bEncrypted))
|
||
return;
|
||
BlkPtr = *BlkPtrRV;
|
||
|
||
f_sprintf( (char *)Title, "HEX DISPLAY OF BLOCK %08X (%s)", (unsigned)ReadAddress,
|
||
(char *)(bIsEncBlock
|
||
? (char *)(bEncrypted
|
||
? (char *)"DECRYPTED"
|
||
: (char *)"ENCRYPTED (RAW)")
|
||
: (char *)"RAW"));
|
||
if (!ViewMenuInit( Title))
|
||
return;
|
||
|
||
uiModFlag = bEncrypted ? MOD_BINARY_ENC : MOD_BINARY;
|
||
while (BytesProcessed < uiViewLen)
|
||
{
|
||
if ((NumBytes = uiViewLen - BytesProcessed) > BytesPerLine)
|
||
NumBytes = BytesPerLine;
|
||
|
||
/* Output the line */
|
||
|
||
if (!ViewAddMenuItem( -1, 0,
|
||
VAL_IS_BINARY_HEX,
|
||
(FLMUINT)BlkPtr, NumBytes,
|
||
FileNumber, FileOffset, NumBytes, uiModFlag,
|
||
Col, Row++, 0,
|
||
FLM_BLACK, FLM_LIGHTGRAY,
|
||
FLM_BLACK, FLM_LIGHTGRAY))
|
||
return;
|
||
FileOffset += (FLMUINT)NumBytes;
|
||
BytesProcessed += NumBytes;
|
||
BlkPtr += NumBytes;
|
||
}
|
||
}
|
||
|
||
|
||
/***************************************************************************
|
||
Name: ViewBlocks
|
||
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 ReadAddress,
|
||
FLMUINT BlkAddress,
|
||
BLK_EXP_p BlkExp
|
||
)
|
||
{
|
||
FLMUINT Option;
|
||
VIEW_INFO SaveView;
|
||
VIEW_INFO DummySave;
|
||
FLMUINT Done = 0;
|
||
FLMUINT Repaint = 1;
|
||
FLMBYTE * BlkPtr = NULL;
|
||
FLMUINT BlkAddress2;
|
||
BLK_EXP BlkExp2;
|
||
FLMUINT SetExp = FALSE;
|
||
FLMUINT Type;
|
||
FLMBOOL bViewHex = FALSE;
|
||
FLMBOOL bViewDecrypted = FALSE;
|
||
FLMUINT uiBytesRead;
|
||
|
||
/* Loop getting commands until hit the exit key */
|
||
|
||
if (!gv_bViewHdrRead)
|
||
ViewReadHdr();
|
||
gv_pViewSearchItem = NULL;
|
||
ViewReset( &SaveView);
|
||
while ((!Done) && (!gv_bViewPoppingStack))
|
||
{
|
||
|
||
/* Display the type of block expected */
|
||
|
||
if (Repaint)
|
||
{
|
||
if (bViewHex)
|
||
{
|
||
ViewHexBlock( ReadAddress, &BlkPtr, bViewDecrypted,
|
||
gv_ViewHdrInfo.FileHdr.uiBlockSize);
|
||
}
|
||
else
|
||
{
|
||
Switch_Statement:
|
||
switch( BlkExp->Type)
|
||
{
|
||
case BHT_NON_LEAF_COUNTS:
|
||
case BHT_NON_LEAF:
|
||
case BHT_NON_LEAF_DATA:
|
||
if (!ViewNonLeafBlk( ReadAddress, BlkAddress,
|
||
&BlkPtr, BlkExp))
|
||
Done = 1;
|
||
break;
|
||
case BHT_LEAF:
|
||
if (!ViewLeafBlk( ReadAddress, BlkAddress,
|
||
&BlkPtr, BlkExp))
|
||
Done = 1;
|
||
break;
|
||
case BHT_FREE:
|
||
if (!ViewAvailBlk( ReadAddress, BlkAddress,
|
||
&BlkPtr, BlkExp))
|
||
Done = 1;
|
||
break;
|
||
case BHT_LFH_BLK:
|
||
if (!ViewLFHBlk( ReadAddress, BlkAddress,
|
||
&BlkPtr, BlkExp))
|
||
Done = 1;
|
||
break;
|
||
case 0xFF:
|
||
if (!ViewBlkRead( ReadAddress, &BlkPtr,
|
||
gv_ViewHdrInfo.FileHdr.uiBlockSize,
|
||
NULL, NULL, &uiBytesRead, FALSE,
|
||
NULL, FALSE, NULL))
|
||
{
|
||
Done = 1;
|
||
}
|
||
else
|
||
{
|
||
BlkExp->Type = BH_GET_TYPE( BlkPtr );
|
||
goto Switch_Statement;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* See what the user wants to do next. */
|
||
|
||
if (!Done)
|
||
{
|
||
if ((SetExp) &&
|
||
((BlkExp->Type == BHT_LEAF) ||
|
||
(BlkExp->Type == BHT_NON_LEAF_COUNTS) ||
|
||
(BlkExp->Type == BHT_NON_LEAF) ||
|
||
(BlkExp->Type == BHT_NON_LEAF_DATA) ))
|
||
{
|
||
BlkExp->LfNum = FB2UW( &BlkPtr [BH_LOG_FILE_NUM]);
|
||
BlkExp->Level = BlkPtr [BH_LEVEL];
|
||
}
|
||
SetExp = FALSE;
|
||
Repaint = 1;
|
||
if (gv_bViewSearching)
|
||
{
|
||
SetSearchTopBottom();
|
||
if ((BlkExp->Type == BHT_LEAF) || (gv_pViewSearchItem == NULL))
|
||
{
|
||
gv_bViewSearching = FALSE;
|
||
ViewEnable();
|
||
Option = ViewGetMenuOption();
|
||
}
|
||
else
|
||
Option = gv_pViewSearchItem->Option;
|
||
}
|
||
else
|
||
{
|
||
ViewEnable();
|
||
Option = ViewGetMenuOption();
|
||
}
|
||
switch( Option)
|
||
{
|
||
case ESCAPE_OPTION:
|
||
Done = 1;
|
||
break;
|
||
case PREV_BLOCK_OPTION:
|
||
ViewReset( &DummySave);
|
||
BlkExp->NextAddr = BlkAddress;
|
||
BlkExp->PrevAddr = 0;
|
||
ReadAddress = BlkAddress = FB2UD( &BlkPtr [BH_PREV_BLK]);
|
||
break;
|
||
case NEXT_BLOCK_OPTION:
|
||
ViewReset( &DummySave);
|
||
BlkExp->NextAddr = 0;
|
||
BlkExp->PrevAddr = BlkAddress;
|
||
ReadAddress = BlkAddress = FB2UD( &BlkPtr [BH_NEXT_BLK]);
|
||
break;
|
||
case PREV_BLOCK_IMAGE_OPTION:
|
||
if (BlkExp->Type == BHT_PCODE_BLK)
|
||
{
|
||
ViewShowError(
|
||
"This option not supported for PCODE blocks");
|
||
Repaint = 0;
|
||
}
|
||
else
|
||
{
|
||
f_memcpy( &BlkExp2, BlkExp, sizeof( BLK_EXP));
|
||
BlkExp2.NextAddr = 0;
|
||
BlkExp2.PrevAddr = 0;
|
||
ViewBlocks( FB2UD( &BlkPtr [BH_PREV_BLK_ADDR]),
|
||
BlkAddress, &BlkExp2);
|
||
}
|
||
break;
|
||
case GOTO_BLOCK_OPTION:
|
||
if (GetBlockAddrType( &BlkAddress2, &Type))
|
||
{
|
||
ViewReset( &DummySave);
|
||
ReadAddress = BlkAddress = BlkAddress2;
|
||
BlkExp->Type = Type;
|
||
BlkExp->Level = 0xFF;
|
||
BlkExp->NextAddr = 0;
|
||
BlkExp->PrevAddr = 0;
|
||
BlkExp->LfNum = 0;
|
||
SetExp = TRUE;
|
||
if (BlkAddress < 2048)
|
||
{
|
||
bViewDecrypted = FALSE;
|
||
bViewHex = TRUE;
|
||
}
|
||
}
|
||
else
|
||
Repaint = 0;
|
||
break;
|
||
case EDIT_OPTION:
|
||
case EDIT_RAW_OPTION:
|
||
if (!ViewEdit( TRUE,
|
||
(Option == EDIT_OPTION) ? TRUE : FALSE))
|
||
Repaint = 0;
|
||
break;
|
||
case HEX_OPTION:
|
||
ViewDisable();
|
||
bViewHex = bViewHex ? FALSE : TRUE;
|
||
if (!bViewHex)
|
||
{
|
||
bViewDecrypted = FALSE;
|
||
}
|
||
break;
|
||
case DECRYPT_OPTION:
|
||
if (bViewHex)
|
||
{
|
||
ViewDisable();
|
||
bViewDecrypted = bViewDecrypted ? FALSE : TRUE;
|
||
}
|
||
else
|
||
{
|
||
Repaint = 0;
|
||
}
|
||
break;
|
||
case SEARCH_OPTION:
|
||
switch( BH_GET_TYPE( BlkPtr))
|
||
{
|
||
case BHT_NON_LEAF_COUNTS:
|
||
case BHT_NON_LEAF:
|
||
case BHT_NON_LEAF_DATA:
|
||
case BHT_LEAF:
|
||
gv_uiViewSearchLfNum = FB2UW( &BlkPtr [BH_LOG_FILE_NUM]);
|
||
if (ViewGetKey())
|
||
gv_bViewPoppingStack = TRUE;
|
||
break;
|
||
case BHT_LFH_BLK:
|
||
{
|
||
VIEW_MENU_ITEM_p vp = gv_pViewMenuCurrItem;
|
||
|
||
/* Determine which logical file, if any we are pointing at */
|
||
|
||
while ((vp != NULL) &&
|
||
(vp->iLabelIndex != LBL_LOGICAL_FILE_NAME))
|
||
vp = vp->PrevItem;
|
||
if (vp != NULL)
|
||
{
|
||
while ((vp != NULL) &&
|
||
(vp->iLabelIndex != LBL_LOGICAL_FILE_NUMBER))
|
||
vp = vp->NextItem;
|
||
}
|
||
if (vp != NULL)
|
||
{
|
||
gv_uiViewSearchLfNum = (FLMUINT)vp->Value;
|
||
if (ViewGetKey())
|
||
gv_bViewPoppingStack = TRUE;
|
||
}
|
||
else
|
||
ViewShowError(
|
||
"Position cursor to a logical file before searching");
|
||
}
|
||
break;
|
||
case BHT_PCODE_BLK:
|
||
{
|
||
VIEW_MENU_ITEM_p vp = gv_pViewMenuCurrItem;
|
||
|
||
/* Determine which logical file, if any we are pointing at */
|
||
|
||
if ((vp->iLabelIndex != LBL_CONTAINER) ||
|
||
(vp->iLabelIndex != LBL_INDEX_CONTAINER))
|
||
{
|
||
while ((vp != NULL) &&
|
||
(vp->iLabelIndex != LBL_INDEX))
|
||
vp = vp->PrevItem;
|
||
}
|
||
if (vp != NULL)
|
||
{
|
||
gv_uiViewSearchLfNum = (FLMUINT)(vp->Option & (~(LOGICAL_FILE_OPTION)));
|
||
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 (Option & LOGICAL_FILE_OPTION)
|
||
ViewLogicalFile( (FLMUINT)(Option & (~(LOGICAL_FILE_OPTION))));
|
||
else if ((Option & LFH_OPTION_ROOT_BLOCK) ||
|
||
(Option & LFH_OPTION_LAST_BLOCK))
|
||
{
|
||
FLMUINT Offset = (FLMUINT)(BH_OVHD +
|
||
(Option & 0x0FFF) * LFH_SIZE);
|
||
|
||
FLMBYTE * LFHPtr = &BlkPtr [Offset];
|
||
|
||
if (Option & LFH_OPTION_ROOT_BLOCK)
|
||
{
|
||
BlkExp2.Level = 0xFF;
|
||
BlkExp2.Type = 0xFF;
|
||
BlkAddress2 = FB2UD( &LFHPtr [LFH_ROOT_BLK_OFFSET]);
|
||
BlkExp2.LfNum = FB2UW( &LFHPtr [LFH_LF_NUMBER_OFFSET]);
|
||
BlkExp2.NextAddr = BlkExp2.PrevAddr = BT_END;
|
||
}
|
||
else
|
||
{
|
||
flmAssert( 0);
|
||
}
|
||
ViewBlocks( BlkAddress2, BlkAddress2, &BlkExp2);
|
||
}
|
||
else if (Option & BLK_OPTION_CHILD_BLOCK)
|
||
{
|
||
FLMBYTE * TempAddrPtr;
|
||
|
||
if (BlkExp->Type == BHT_NON_LEAF_DATA)
|
||
TempAddrPtr = &BlkPtr [(Option & 0xFFF) + BNE_DATA_CHILD_BLOCK];
|
||
else
|
||
TempAddrPtr = &BlkPtr [(Option & 0xFFF) + BNE_CHILD_BLOCK];
|
||
|
||
BlkAddress2 = FB2UD( TempAddrPtr);
|
||
f_memcpy( &BlkExp2, BlkExp, sizeof( BLK_EXP));
|
||
BlkExp2.NextAddr = 0;
|
||
BlkExp2.PrevAddr = 0;
|
||
if (BlkExp2.Level == 0xFF)
|
||
BlkExp2.Level = BlkPtr [BH_LEVEL] - 1;
|
||
else
|
||
BlkExp2.Level--;
|
||
if (!BlkExp2.Level)
|
||
BlkExp2.Type = BHT_LEAF;
|
||
ViewBlocks( BlkAddress2, BlkAddress2, &BlkExp2);
|
||
}
|
||
else
|
||
Repaint = 0;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
f_free( &BlkPtr);
|
||
ViewRestore( &SaveView);
|
||
}
|
||
|
||
/********************************************************************
|
||
Desc: ?
|
||
*********************************************************************/
|
||
FLMINT GetBlockAddrType(
|
||
FLMUINT * BlkAddressRV,
|
||
FLMUINT * BlkTypeRV)
|
||
{
|
||
char TempBuf [20];
|
||
FLMUINT i;
|
||
FLMUINT c;
|
||
FLMUINT BadDigit;
|
||
FLMUINT GotAddress = FALSE;
|
||
FLMUINT GotType = FALSE;
|
||
FLMUINT GetOK = 1;
|
||
FLMUINT uiNumCols;
|
||
FLMUINT uiNumRows;
|
||
|
||
f_conGetScreenSize( &uiNumCols, &uiNumRows);
|
||
|
||
/* First get the block address */
|
||
|
||
while ((!GotAddress) && (GetOK))
|
||
{
|
||
BadDigit = FALSE;
|
||
f_conSetBackFore( FLM_BLACK, FLM_WHITE);
|
||
f_conClearScreen( 0, uiNumRows - 2);
|
||
ViewAskInput( "Enter Block Address (in hex): ",
|
||
TempBuf, sizeof( TempBuf));
|
||
if ((f_stricmp( TempBuf, "\\") == 0) ||
|
||
(!TempBuf [0]))
|
||
{
|
||
GetOK = 0;
|
||
break;
|
||
}
|
||
i = 0;
|
||
*BlkAddressRV = 0;
|
||
while ((TempBuf [i]) && (i < 8))
|
||
{
|
||
(*BlkAddressRV) <<= 4;
|
||
c = TempBuf [i];
|
||
if ((c >= '0') && (c <= '9'))
|
||
(*BlkAddressRV) += (FLMUINT)(c - '0');
|
||
else if ((c >= 'a') && (c <= 'f'))
|
||
(*BlkAddressRV) += (FLMUINT)(c - 'a' + 10);
|
||
else if ((c >= 'A') && (c <= 'F'))
|
||
(*BlkAddressRV) += (FLMUINT)(c - 'A' + 10);
|
||
else
|
||
{
|
||
BadDigit = TRUE;
|
||
break;
|
||
}
|
||
i++;
|
||
}
|
||
if (BadDigit)
|
||
ViewShowError(
|
||
"Illegal digit in number - must be hex digits");
|
||
else if (TempBuf [i])
|
||
ViewShowError(
|
||
"Too many characters in number");
|
||
else
|
||
GotAddress = TRUE;
|
||
}
|
||
|
||
/* Next get the block type */
|
||
|
||
if (GetOK)
|
||
{
|
||
f_conSetBackFore( FLM_BLACK, FLM_WHITE);
|
||
f_conClearScreen( 0, uiNumRows - 1);
|
||
f_conStrOutXY( "View: 1=Leaf, 2=NLeafCnts, 3=NLeafVar, 4=NLeafFix, 5=Avail, 6=LFH: ",
|
||
0, uiNumRows - 1);
|
||
}
|
||
while ((GetOK) && (!GotType))
|
||
{
|
||
c = f_conGetKey();
|
||
switch( c)
|
||
{
|
||
case FKB_ESCAPE:
|
||
case '0':
|
||
GetOK = 0;
|
||
break;
|
||
case '1':
|
||
GotType = TRUE;
|
||
*BlkTypeRV = BHT_LEAF;
|
||
break;
|
||
case '2':
|
||
GotType = TRUE;
|
||
*BlkTypeRV = BHT_NON_LEAF_COUNTS;
|
||
break;
|
||
case '3':
|
||
GotType = TRUE;
|
||
*BlkTypeRV = BHT_NON_LEAF;
|
||
break;
|
||
case '4':
|
||
GotType = TRUE;
|
||
*BlkTypeRV = BHT_NON_LEAF_DATA;
|
||
break;
|
||
case '5':
|
||
GotType = TRUE;
|
||
*BlkTypeRV = BHT_FREE;
|
||
break;
|
||
case '6':
|
||
GotType = TRUE;
|
||
*BlkTypeRV = BHT_LFH_BLK;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
f_conClearScreen( 0, uiNumRows - 2);
|
||
ViewEscPrompt();
|
||
return( GetOK);
|
||
}
|
||
|
||
/********************************************************************
|
||
Desc: ?
|
||
*********************************************************************/
|
||
FSTATIC void SetSearchTopBottom(
|
||
void
|
||
)
|
||
{
|
||
if (gv_pViewSearchItem == NULL)
|
||
{
|
||
gv_pViewMenuCurrItem = NULL;
|
||
gv_uiViewMenuCurrItemNum = 0;
|
||
gv_uiViewCurrFileOffset = 0;
|
||
gv_uiViewCurrFileNumber = 0;
|
||
gv_uiViewTopRow = 0;
|
||
}
|
||
else
|
||
{
|
||
gv_pViewMenuCurrItem = gv_pViewSearchItem;
|
||
gv_uiViewMenuCurrItemNum = gv_pViewSearchItem->ItemNum;
|
||
gv_uiViewCurrFileOffset = gv_pViewSearchItem->ModFileOffset;
|
||
gv_uiViewCurrFileNumber = gv_pViewSearchItem->ModFileNumber;
|
||
gv_uiViewTopRow = gv_pViewSearchItem->Row;
|
||
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->Row)
|
||
{
|
||
gv_uiViewBottomRow = gv_pViewMenuLastItem->Row;
|
||
if (gv_uiViewBottomRow < LINES_PER_PAGE)
|
||
gv_uiViewTopRow = 0;
|
||
else
|
||
gv_uiViewTopRow = gv_uiViewBottomRow - LINES_PER_PAGE + 1;
|
||
}
|
||
}
|