Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

199 lines
4.9 KiB

/*****************************************************************************
* *
* BTKTLONG.C *
* *
* Copyright (C) Microsoft Corporation 1989, 1994. *
* All Rights reserved. *
* *
******************************************************************************
* *
* Module Intent *
* *
* Functions for LONG keys. *
*
*****************************************************************************/
#include "help.h"
#include <search.h>
static int __cdecl CompareBtree(const void* pelem1, const void* pelem2);
// #include "inc\btpriv.h"
/***************************************************************************\
*
- Function: BkScanLInternal( bk, key, wLevel, qbthr )
-
* Purpose: Scan an internal node for a LONG key and return child BK.
*
* ASSUMES
* args IN: bk - BK of internal node to scan
* key - key to search for
* wLevel - level of btree bk lives on
* qbthr - btree header containing cache, and btree specs
*
* PROMISES
* returns: bk of subtree that might contain key; bkNil on error
* args OUT: qbthr->qCache - bk's block will be cached
*
* Side Effects: bk's block will be cached
* +++
*
* Method: Should use binary search. Doesn't, yet.
*
\***************************************************************************/
DWORD STDCALL BkScanLInternal(DWORD bkCaller, KEY key, int wLevel, QBTHR qbthr, int* qiKey )
{
QCB qcb;
PBYTE q;
int cKeys;
BK bk;
#ifndef _X86_
INT isdff = ISdffFileIdHf( qbthr->hf );
LONG lKey;
#endif
if ((qcb = QFromBk(bkCaller, wLevel, qbthr)) == (QCB) NULL) {
return bkNil;
}
q = qcb->db.rgbBlock;
cKeys = qcb->db.cKeys;
#ifdef _X86_
bk = *(BK *) q;
#else
bk = WQuickMapSDFF(isdff, TE_WORD, q);
#endif
q += sizeof(BK);
#ifndef _X86_
lKey = LQuickMapSDFF(isdff, TE_LONG, (QV) key);
#endif
while (cKeys-- > 0) {
#ifdef _X86_
if (*(LONG *) key >= *(LONG *) q) {
q += sizeof(LONG);
bk = *(BK *) q;
#else
if (lKey >= LQuickMapSDFF(isdff, TE_LONG, q)) {
q += sizeof(LONG);
bk = WQuickMapSDFF(isdff, TE_WORD, q);
#endif
q += sizeof(BK);
}
else
break;
}
if (qiKey)
*qiKey = q - (QB) qcb->db.rgbBlock;
return bk;
}
/***************************************************************************\
*
- Function: RcScanLLeaf( bk, key, wLevel, qbthr, qRec, qBtpos )
-
* Purpose: Scan a leaf node for a key and copy the associated data.
*
* ASSUMES
* args IN: bk - the leaf block
* key - the key we're looking for
* wLevel - the level of leaves (unnecessary)
* qbthr - the btree header
*
* PROMISES
* returns: rcSuccess if found; rcNoExists if not found
* args OUT: qRec - if found, record gets copied into this buffer
* qbtpos - pos of first key >= key goes here
*
* Notes: If we are scanning for a key greater than any key in this
* block, the pos returned will be invalid and will point just
* past the last valid key in this block.
* +++
*
* Method: Should use binary search if fixed record size. Doesn't, yet.
*
\***************************************************************************/
RC STDCALL RcScanLLeaf(DWORD bk, KEY key, int wLevel, QBTHR qbthr, void* qRec, QBTPOS qbtpos)
{
QCB qcb;
QB qb;
int cKey, cMaxKey;
PBYTE ptest = NULL;
#ifndef _X86_
INT isdff = ISdffFileIdHf( qbthr->hf);
LONG lKey = LQuickMapSDFF( isdff, TE_LONG, (QV)key);
LONG lThisKey;
#endif
if ((qcb = QFromBk(bk, wLevel, qbthr)) == (QCB) NULL)
return rcBtreeError;
rcBtreeError = rcNoExists;
qb = qcb->db.rgbBlock + 2 * sizeof(BK);
cMaxKey = (int) qcb->db.cKeys; // convert to 32 bits
#if 0
// 01-Jun-1995 [ralphw] I took this out because in hcrtf, which uses the
// same code, not all btrees are sorted correctly (yet they still work)
if (!qbtpos && qbthr->cbRecordSize && cMaxKey) {
ptest = (PBYTE) bsearch((void*) key, (void*) qb, cMaxKey,
sizeof(LONG) + qbthr->cbRecordSize, &CompareBtree);
}
#endif
for (cKey = 0; cKey < cMaxKey; cKey++) {
#ifdef _X86_
if (*(LONG *) key > *(LONG *) qb) { // still looking for key
#else
lThisKey = LQuickMapSDFF (isdff, TE_LONG, qb);
if (lKey > lThisKey) {
#endif
qb += sizeof(LONG);
if (qbthr->cbRecordSize)
qb += qbthr->cbRecordSize;
else
qb += CbSizeRec(qb, qbthr);
}
#ifdef _X86_
else if (*(LONG *) key < *(LONG *) qb) { // key not found
#else
else if (lKey < lThisKey ) {
#endif
break;
}
else { // matched the key
ptest = qb;
break;
}
}
if (ptest) {
if (qRec != NULL) {
// REVIEW: why not CopyMemory? Do they actually overlap?
MoveMemory(qRec, ptest + sizeof(LONG),
(LONG) CbSizeRec(ptest + sizeof(LONG), qbthr));
}
rcBtreeError = rcSuccess;
}
if (qbtpos != (QBTPOS) NULL) {
qbtpos->bk = bk;
qbtpos->iKey = qb - (QB) qcb->db.rgbBlock;
qbtpos->cKey = cKey;
}
return rcBtreeError;
}
static int __cdecl CompareBtree(const void* pelem1, const void* pelem2)
{
return (*(LONG *) pelem1 - *(LONG *) pelem2);
}