Source code of Windows XP (NT5)
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.

285 lines
7.5 KiB

  1. /*****************************************************************************
  2. * *
  3. * BTMAPRD.C *
  4. * *
  5. * Copyright (C) Microsoft Corporation 1989 - 1994. *
  6. * All Rights reserved. *
  7. * *
  8. ******************************************************************************
  9. * *
  10. * Module Intent *
  11. * *
  12. * Routines to read btree map files. *
  13. * *
  14. ******************************************************************************
  15. * *
  16. * Current Owner: UNDONE *
  17. * *
  18. *****************************************************************************/
  19. /*****************************************************************************
  20. *
  21. * Revision History: Created 12/15/89 by KevynCT
  22. *
  23. * 08/21/90 JohnSc autodocified
  24. * 3/05/97 erinfox Change errors to HRESULTS
  25. *
  26. *****************************************************************************/
  27. static char s_aszModule[] = __FILE__; /* For error report */
  28. #include <mvopsys.h>
  29. #include <orkin.h>
  30. #include <iterror.h>
  31. #include <misc.h>
  32. #include <wrapstor.h>
  33. #include <_mvutil.h>
  34. /*----------------------------------------------------------------------------*
  35. | Public functions |
  36. *----------------------------------------------------------------------------*/
  37. /***************************************************************************
  38. *
  39. - Function: HmapbtOpenHfs(hfs, szName)
  40. -
  41. * Purpose: Returns an HMAPBT for the btree map named szName.
  42. *
  43. * ASSUMES
  44. * args IN: hfs - file system wherein lives the btree map file
  45. * szName - name of the btree map file
  46. *
  47. * PROMISES
  48. * returns: NULL on error (call RcGetFSError()); or a valid HMAPBT.
  49. * +++
  50. *
  51. * Method: Opens the file, allocates a hunk of memory, reads the
  52. * file into the memory, and closes the file.
  53. *
  54. ***************************************************************************/
  55. HMAPBT FAR PASCAL HmapbtOpenHfs(HFS hfs, LPWSTR szName, PHRESULT phr)
  56. {
  57. HF hf;
  58. HMAPBT hmapbt;
  59. QMAPBT qmapbt;
  60. FILEOFFSET foSize;
  61. if(hfs == NULL)
  62. {
  63. SetErrCode (phr, E_INVALIDARG);
  64. return NULL;
  65. }
  66. hf = HfOpenHfs(hfs, szName, fFSOpenReadOnly, phr);
  67. if(hf == hfNil)
  68. return NULL;
  69. foSize = FoSizeHf(hf, phr);
  70. if (foSize.dwHigh)
  71. {
  72. exit0:
  73. RcCloseHf(hf);
  74. return(NULL);
  75. }
  76. if ((hmapbt = _GLOBALALLOC(GMEM_ZEROINIT|GMEM_SHARE| GMEM_MOVEABLE,
  77. foSize.dwOffset)) == NULL)
  78. {
  79. SetErrCode (phr, E_OUTOFMEMORY);
  80. goto exit0;
  81. }
  82. qmapbt = (QMAPBT) _GLOBALLOCK(hmapbt);
  83. FoSeekHf(hf, foNil, wFSSeekSet, phr);
  84. if(LcbReadHf( hf, qmapbt, (LONG)foSize.dwOffset, phr) != (LONG)foSize.dwOffset )
  85. {
  86. SetErrCode (phr, E_FILEINVALID);
  87. _GLOBALUNLOCK(hmapbt);
  88. _GLOBALFREE(hmapbt);
  89. goto exit0;
  90. }
  91. else
  92. {
  93. /* Swap the data for MAC */
  94. #ifdef _BIG_E
  95. int i;
  96. QMAPREC qMapRec;
  97. qmapbt->cTotalBk = SWAPWORD(qmapbt->cTotalBk);
  98. for(i =qmapbt->cTotalBk, qMapRec = qmapbt->table; i >0; i--)
  99. {
  100. qMapRec->cPreviousKeys = SWAPLONG(qMapRec->cPreviousKeys);
  101. qMapRec->bk = SWAPLONG(qMapRec->bk);
  102. qMapRec++;
  103. }
  104. #endif
  105. _GLOBALUNLOCK(hmapbt);
  106. }
  107. RcCloseHf(hf);
  108. return hmapbt;
  109. }
  110. /***************************************************************************
  111. *
  112. - Function: RcCloseHmapbt(hmapbt)
  113. -
  114. * Purpose: Get rid of a btree map.
  115. *
  116. * ASSUMES
  117. * args IN: hmapbt - handle to the btree map
  118. *
  119. * PROMISES
  120. * returns: rc
  121. * args OUT: hmapbt - no longer valid
  122. * +++
  123. *
  124. * Method: Free the memory.
  125. *
  126. ***************************************************************************/
  127. HRESULT FAR PASCAL RcCloseHmapbt(HMAPBT hmapbt)
  128. {
  129. if(hmapbt != NULL)
  130. {
  131. _GLOBALFREE(hmapbt);
  132. return S_OK;
  133. }
  134. else
  135. return (E_INVALIDARG);
  136. }
  137. /***************************************************************************
  138. *
  139. - Function: RcIndexFromKeyHbt(hbt, hmapbt, ql, key)
  140. -
  141. * Purpose:
  142. *
  143. * ASSUMES
  144. * args IN: hbt - a btree handle
  145. * hmapbt - map to hbt
  146. * key - key
  147. * globals IN:
  148. * state IN:
  149. *
  150. * PROMISES
  151. * returns: rc
  152. * args OUT: ql - gives you the ordinal of the key in the btree
  153. * (i.e. key is the (*ql)th in the btree)
  154. * +++
  155. *
  156. * Method: Looks up the key, uses the btpos and the hmapbt to
  157. * determine the ordinal.
  158. *
  159. ***************************************************************************/
  160. HRESULT FAR PASCAL RcIndexFromKeyHbt(HBT hbt, HMAPBT hmapbt, QL ql, KEY key)
  161. {
  162. BTPOS btpos;
  163. QMAPBT qmapbt;
  164. HRESULT fRet;
  165. SHORT i;
  166. if(( hbt == NULL) || ( hmapbt == NULL ) )
  167. return (E_INVALIDARG);
  168. qmapbt = (QMAPBT) _GLOBALLOCK(hmapbt);
  169. if(qmapbt->cTotalBk == 0)
  170. {
  171. fRet = E_FAIL;
  172. exit0:
  173. _GLOBALUNLOCK (hmapbt);
  174. return fRet;
  175. }
  176. if ((fRet = RcLookupByKey(hbt, key, &btpos, NULL)) == S_OK)
  177. {
  178. for(i = 0; i < qmapbt->cTotalBk; i++)
  179. {
  180. if (qmapbt->table[i].bk == btpos.bk)
  181. break;
  182. }
  183. if (i == qmapbt->cTotalBk)
  184. {
  185. /* Something is terribly wrong, if we are here */
  186. fRet = E_ASSERT;
  187. goto exit0;
  188. }
  189. *ql = qmapbt->table[i].cPreviousKeys + btpos.cKey;
  190. }
  191. goto exit0;
  192. }
  193. /***************************************************************************
  194. *
  195. - Function: RcKeyFromIndexHbt(hbt, hmapbt, key, li)
  196. -
  197. * Purpose: Gets the (li)th key from a btree.
  198. *
  199. * ASSUMES
  200. * args IN: hbt - btree handle
  201. * hmapbt - map to the btree
  202. * li - ordinal
  203. *
  204. * PROMISES
  205. * returns: rc
  206. * args OUT: key - (li)th key copied here on success
  207. * +++
  208. *
  209. * Method: We roll our own btpos using the hmapbt, then use
  210. * RcLookupByPos() to get the key.
  211. *
  212. ***************************************************************************/
  213. HRESULT FAR PASCAL RcKeyFromIndexHbt( HBT hbt, HMAPBT hmapbt,
  214. KEY key, int iLen, LONG li)
  215. {
  216. BTPOS btpos;
  217. BTPOS btposNew;
  218. QMAPBT qmapbt;
  219. SHORT i;
  220. LONG liDummy;
  221. HRESULT fRet;
  222. if ((hbt == NULL) || (hmapbt == NULL))
  223. return E_INVALIDARG;
  224. /* Given index N, get block having greatest PreviousKeys < N.
  225. * Use linear search for now.
  226. */
  227. qmapbt = (QMAPBT) _GLOBALLOCK(hmapbt);
  228. if(qmapbt->cTotalBk == 0)
  229. {
  230. _GLOBALUNLOCK(hmapbt);
  231. return (E_FAIL);
  232. }
  233. for(i = 0 ;; i++)
  234. {
  235. if(i + 1 >= qmapbt->cTotalBk)
  236. break;
  237. if(qmapbt->table[i+1].cPreviousKeys >= li)
  238. break;
  239. }
  240. btpos.bk = qmapbt->table[i].bk;
  241. btpos.cKey = 0;
  242. btpos.iKey = 2 * sizeof(BK); /* start at the zero-th key */
  243. _GLOBALUNLOCK(hmapbt);
  244. /*
  245. * Scan the block for the n-th key
  246. */
  247. if ((fRet = RcOffsetPos( hbt, &btpos,
  248. (LONG)(li - qmapbt->table[i].cPreviousKeys),
  249. &liDummy, &btposNew)) != S_OK)
  250. return fRet;
  251. return RcLookupByPos(hbt, &btposNew, key, iLen, NULL);
  252. }