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.
 
 
 
 
 
 

226 lines
5.2 KiB

/*****************************************************************************
* *
* BTMAPRD.C *
* *
* Copyright (C) Microsoft Corporation 1989, 1990-1994 *
* All Rights reserved. *
* *
******************************************************************************
* *
* Module Intent *
* *
* Routines to read btree map files. *
*
*****************************************************************************/
#include "help.h"
#pragma hdrstop
// #include "inc\btpriv.h"
/***************************************************************************\
*
- Function: HmapbtOpenHfs( hfs, szName )
-
* Purpose: Returns an HMAPBT for the btree map named szName.
*
* ASSUMES
* args IN: hfs - file system wherein lives the btree map file
* szName - name of the btree map file
*
* PROMISES
* returns: NULL on error (call RcGetBtreeError()); or a valid HMAPBT.
* +++
*
* Method: Opens the file, allocates a hunk of memory, reads the
* file into the memory, and closes the file.
*
\***************************************************************************/
HMAPBT STDCALL HmapbtOpenHfs(HFS hfs, LPCSTR szName)
{
HF hf;
HMAPBT hmapbt;
QMAPBT qmapbt;
LONG lcb;
if (hfs == NULL) {
rcBtreeError = rcBadHandle;
return NULL;
}
hf = HfOpenHfs(hfs, (LPSTR) szName, fFSOpenReadOnly);
if (hf == NULL) {
rcBtreeError = RcGetFSError();
return NULL;
}
lcb = LcbSizeHf(hf);
#ifdef _X86_
hmapbt = GhAlloc(GPTR, lcb);
#else
hmapbt = GhAlloc(GPTR, (lcb+2)*2); // MIPS, word padding inserted
#endif
if (hmapbt != NULL) {
qmapbt = (QMAPBT) PtrFromGh(hmapbt);
LSeekHf(hf, 0L, wFSSeekSet);
if (LcbReadHf(hf, qmapbt, lcb) != lcb) {
rcBtreeError = RcGetFSError();
FreeGh(hmapbt);
hmapbt = NULL;
}
#ifndef _X86_
else { // SDFF translation:
LcbMapSDFF( ISdffFileIdHf( hf) , SE_MAPBT, qmapbt, qmapbt);
}
#endif
}
else
rcBtreeError = rcOutOfMemory;
RcCloseHf(hf);
return hmapbt;
}
/***************************************************************************\
*
- Function: RcCloseHmapbt( hmapbt )
-
* Purpose: Get rid of a btree map.
*
* ASSUMES
* args IN: hmapbt - handle to the btree map
*
* PROMISES
* returns: rc
* args OUT: hmapbt - no longer valid
* +++
*
* Method: Free the memory.
*
\***************************************************************************/
RC STDCALL RcCloseHmapbt(HMAPBT hmapbt)
{
if (hmapbt != NULL) {
FreeGh(hmapbt);
return rcSuccess;
}
else
return rcBtreeError = rcBadHandle;
}
/***************************************************************************\
*
- Function: RcIndexFromKeyHbt( hbt, hmapbt, ql, key )
-
* Purpose:
*
* ASSUMES
* args IN: hbt - a btree handle
* hmapbt - map to hbt
* key - key
* globals IN:
* state IN:
*
* PROMISES
* returns: rc
* args OUT: ql - gives you the ordinal of the key in the btree
* (i.e. key is the (*ql)th in the btree)
* +++
*
* Method: Looks up the key, uses the btpos and the hmapbt to
* determine the ordinal.
*
\***************************************************************************/
RC STDCALL RcIndexFromKeyHbt(HBT hbt, HMAPBT hmapbt, QL ql, KEY key)
{
BTPOS btpos;
QMAPBT qmapbt;
int i;
if ((hbt == NULL) || (hmapbt == NULL))
return rcBtreeError = rcBadHandle;
qmapbt = (QMAPBT) PtrFromGh(hmapbt);
if (qmapbt->cTotalBk == 0) {
return rcBtreeError = rcFailure;
}
RcLookupByKey(hbt, key, &btpos, NULL); //???? return code ????*/
for (i = 0; i < qmapbt->cTotalBk; i++) {
if (qmapbt->table[i].bk == btpos.bk) break;
}
if (i == qmapbt->cTotalBk) {
// Something is terribly wrong, if we are here
return rcBtreeError = rcFailure;
}
*ql = qmapbt->table[i].cPreviousKeys + btpos.cKey;
return rcBtreeError = rcSuccess;
}
/***************************************************************************\
*
- Function: RcKeyFromIndexHbt( hbt, hmapbt, key, li )
-
* Purpose: Gets the (li)th key from a btree.
*
* ASSUMES
* args IN: hbt - btree handle
* hmapbt - map to the btree
* li - ordinal
*
* PROMISES
* returns: rc
* args OUT: key - (li)th key copied here on success
* +++
*
* Method: We roll our own btpos using the hmapbt, then use
* RcLookupByPos() to get the key.
*
\***************************************************************************/
RC STDCALL RcKeyFromIndexHbt(HBT hbt, HMAPBT hmapbt, KEY key, LONG li)
{
BTPOS btpos;
BTPOS btposNew;
QMAPBT qmapbt;
int i;
LONG liDummy;
if ((hbt == NULL) || (hmapbt == NULL))
return rcBtreeError = rcBadHandle;
/*
* Given index N, get block having greatest PreviousKeys < N. Use
* linear search for now.
*/
qmapbt = (QMAPBT) PtrFromGh( hmapbt );
if (qmapbt->cTotalBk == 0)
return rcBtreeError = rcFailure;
for (i = 0;; i++) {
if (i + 1 >= qmapbt->cTotalBk)
break;
if (qmapbt->table[i + 1].cPreviousKeys >= li)
break;
}
btpos.bk = qmapbt->table[i].bk;
btpos.cKey = 0;
btpos.iKey = 2 * sizeof(BK); // start at the zero-th key
// Scan the block for the n-th key
if (RcOffsetPos(hbt, &btpos, (LONG) (li - qmapbt->table[i].cPreviousKeys),
&liDummy, &btposNew) != rcSuccess)
return rcBtreeError = rcNoExists;
return RcLookupByPos(hbt, &btposNew, key, NULL);
}