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.

416 lines
10 KiB

4 years ago
  1. /*****************************************************************************
  2. * *
  3. * DELAY.CPP *
  4. * *
  5. * Copyright (C) Microsoft Corporation 1990-1994 *
  6. * All Rights reserved. *
  7. * *
  8. ******************************************************************************
  9. * *
  10. * Module Intent *
  11. * *
  12. * This module handles delayed address processing. It is required because *
  13. * physical addresses are not known until after a 16K block can be *
  14. * processed with Zeck compression. Instead of writing addresses out *
  15. * when they are encountered, the idfcp is recorded with a DelayExecution() *
  16. * call. Then, after a block gets Zeck compressed and the addresses are *
  17. * known, we go through this information and write out all the correct *
  18. * addresses. *
  19. *****************************************************************************/
  20. #include "stdafx.h"
  21. #pragma hdrstop
  22. #ifdef _DEBUG
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. /*****************************************************************************
  27. * *
  28. * Defines *
  29. * *
  30. *****************************************************************************/
  31. // Maximum value of an object offset
  32. const int MAX_OBJRG = (1 << CBITS_OBJOFF);
  33. /*****************************************************************************
  34. * *
  35. * Typedefs *
  36. * *
  37. *****************************************************************************/
  38. // Delay Execution: Browse info
  39. typedef struct {
  40. PSTR szMajor, szMinor;
  41. IDFCP idfcp;
  42. } DEBROWSE, * QDEBROWSE;
  43. // Delay Execution: Title info
  44. typedef struct {
  45. PSTR szTitle;
  46. IDFCP idfcp;
  47. } DETITLE, * LPDETITLE;
  48. // Delay Execution: Context string info
  49. typedef struct {
  50. HASH hash;
  51. IDFCP idfcp;
  52. WORD wObjrg;
  53. } DECONTEXT, * QDECONTEXT;
  54. // Delay Execution: Keyword info
  55. typedef struct {
  56. CTable* ptbl;
  57. KT chKey;
  58. IDFCP idfcp;
  59. WORD wObjrg;
  60. } DEKEYWORD, * LPDEKEYWORD;
  61. /*****************************************************************************
  62. * *
  63. * Static Variables *
  64. * *
  65. *****************************************************************************/
  66. static CDrg* pdrgBrowse;
  67. static CDrg* pdrgTitle;
  68. static CDrg* pdrgContext;
  69. static CDrg* pdrgKeyword;
  70. static CDrg* pdrgWObjrg; // DRG of wObjrg in each FCP
  71. static WORD wObjrgTotal;
  72. static IDFCP _idfcpFirst; // id of first FCP in above DRG
  73. /*****************************************************************************
  74. * *
  75. * Prototypes *
  76. * *
  77. *****************************************************************************/
  78. void STDCALL FInitDelayExecution(void)
  79. {
  80. _idfcpFirst = FIRST_IDFCP; // REVIEW;
  81. wObjrgTotal = 0;
  82. pdrgTitle = new CDrg(sizeof(DETITLE), 100, 100);
  83. pdrgContext = new CDrg(sizeof(DECONTEXT), 100, 100);
  84. pdrgKeyword = new CDrg(sizeof(DEKEYWORD), 100, 100);
  85. pdrgWObjrg = new CDrg(sizeof(WORD), 100, 100);
  86. }
  87. void STDCALL EndDelayExecution(void)
  88. {
  89. if (pdrgBrowse) {
  90. delete pdrgBrowse;
  91. pdrgBrowse = NULL;
  92. }
  93. // Use pdrgTitle to determine if any were created
  94. if (pdrgTitle) {
  95. delete pdrgWObjrg;
  96. delete pdrgKeyword;
  97. delete pdrgContext;
  98. delete pdrgTitle;
  99. pdrgTitle = NULL;
  100. pdrgContext = NULL;
  101. pdrgKeyword = NULL;
  102. pdrgWObjrg = NULL;
  103. }
  104. }
  105. /***************************************************************************
  106. *
  107. - Name: RcRegisterWObjrg
  108. -
  109. * Purpose:
  110. * Used to register the number of object regions in every
  111. * FCP, in order to calculate cumulative object offsets when
  112. * determining physical addresses.
  113. *
  114. * Arguments:
  115. * idfcp: id of FCP
  116. * wObjrg: Number of object regions in FCP
  117. *
  118. * Returns:
  119. * Return code:
  120. * RC_Success: success
  121. * RC_Failure: Current FCP overflows object region count. All
  122. * FCPs up to but not including this one must be
  123. * flushed.
  124. * RC_TooBig: Current FCP overflows object region count all
  125. * by itself. Paragraph contains too many objects
  126. * and cannot be compiled.
  127. * RC_OutOfMemory: Out of memory.
  128. *
  129. * Globals:
  130. * Uses the global wObjrgTotal to accumulate current total of
  131. * object offsets.
  132. *
  133. * +++
  134. *
  135. * Notes:
  136. *
  137. ***************************************************************************/
  138. RC_TYPE STDCALL RcRegisterWObjrg(IDFCP idfcp, UINT wObjrg)
  139. {
  140. Unreferenced(idfcp); // in non-debug build
  141. // This assert happens in dolphin\crt.hpj -- but what does it mean?
  142. // ASSERT(_idfcpFirst + pdrgWObjrg->Count() == idfcp);
  143. /*
  144. * REVIEW: This assert is valid because this condition is checked in
  145. * RcOutputCommand, and outputting an end of text command is the last
  146. * thing that ever happens to any FCP. However, the constants they check
  147. * against are declared differently, although they currently evaluate to
  148. * the same thing.
  149. */
  150. ASSERT(wObjrg <= MAX_OBJRG);
  151. pdrgWObjrg->Add(&wObjrg);
  152. wObjrgTotal += wObjrg;
  153. if (wObjrgTotal > MAX_OBJRG)
  154. return RC_Failure;
  155. return RC_Success;
  156. }
  157. /***************************************************************************
  158. *
  159. - Name: FKeepFlushing
  160. -
  161. * Purpose:
  162. * This function is called to flush the zeck buffer until the
  163. * total object region count is low enough to proceed.
  164. *
  165. * Arguments:
  166. * none
  167. *
  168. * Returns:
  169. * TRUE if the current object region total is still too large.
  170. *
  171. * Globals Used:
  172. * wObjrgTotal
  173. *
  174. ***************************************************************************/
  175. BOOL STDCALL FKeepFlushing(void)
  176. {
  177. return (wObjrgTotal > MAX_OBJRG);
  178. }
  179. void STDCALL FDelayExecutionBrowse(PSTR szMajor, PSTR szMinor,
  180. IDFCP idfcp)
  181. {
  182. DEBROWSE debrowse;
  183. if (!pdrgBrowse)
  184. pdrgBrowse = new CDrg(sizeof(DEBROWSE), 100, 100);
  185. if (strlen(szMajor) >= 50) {
  186. VReportError(HCERR_MAJOR_BROWSE_TOO_BIG, &errHpj, szMajor);
  187. szMajor[50] = '\0';
  188. }
  189. if (strlen(szMinor) >= 50) {
  190. VReportError(HCERR_MINOR_BROWSE_TOO_BIG, &errHpj, szMinor);
  191. szMinor[50] = '\0';
  192. }
  193. debrowse.szMajor = lcStrDup(szMajor);
  194. debrowse.szMinor = lcStrDup(szMinor);
  195. debrowse.idfcp = idfcp;
  196. pdrgBrowse->Add(&debrowse);
  197. }
  198. void STDCALL FDelayExecutionTitle(PCSTR szTitle, IDFCP idfcp)
  199. {
  200. DETITLE detitle;
  201. detitle.szTitle = lcStrDup(szTitle);
  202. detitle.idfcp = idfcp;
  203. pdrgTitle->Add(&detitle);
  204. }
  205. void STDCALL FDelayExecutionContext(HASH hash, IDFCP idfcp, UINT wObjrg)
  206. {
  207. DECONTEXT decontext;
  208. decontext.hash = hash;
  209. decontext.idfcp = idfcp;
  210. decontext.wObjrg = wObjrg;
  211. pdrgContext->Add(&decontext);
  212. }
  213. void STDCALL FDelayExecutionKeyword(CTable* ptbl, KT chKey, IDFCP idfcp,
  214. UINT wObjrg)
  215. {
  216. DEKEYWORD dekeyword;
  217. dekeyword.ptbl = ptbl;
  218. dekeyword.chKey = chKey;
  219. dekeyword.idfcp = idfcp;
  220. dekeyword.wObjrg = wObjrg;
  221. pdrgKeyword->Add(&dekeyword);
  222. }
  223. RC_TYPE STDCALL RcExecuteDelayedExecution(DWORD ulBlknum, IDFCP idfcpFirst,
  224. IDFCP idfcpLast, BROWSE_CALLBACK pfnBrowseCallback)
  225. {
  226. WORD * rgwOffset;
  227. WORD iwOffset;
  228. PA pa;
  229. RC_TYPE rc;
  230. LPDETITLE lpDeTitle;
  231. ASSERT(_idfcpFirst == idfcpFirst);
  232. // REVIEW ! ! REVIEW ! !
  233. if (idfcpFirst > idfcpLast)
  234. return RC_Success;
  235. // First, set up addresses:
  236. pa.blknum = ulBlknum;
  237. ASSERT((idfcpLast - idfcpFirst + 1) * sizeof(WORD) < 63L * 1024L);
  238. CMem gmem((idfcpLast - idfcpFirst + 1) * sizeof(WORD));
  239. rgwOffset = (WORD *) gmem.pb;
  240. ASSERT((IDFCP) pdrgWObjrg->Count() > idfcpLast - idfcpFirst);
  241. rgwOffset[0] = 0;
  242. for (iwOffset = 1; (IDFCP) iwOffset <= idfcpLast - idfcpFirst;
  243. ++iwOffset) {
  244. rgwOffset[iwOffset] = rgwOffset[iwOffset - 1] +
  245. *(WORD*) pdrgWObjrg->GetBasePtr();
  246. // This call removes the iwOffset-1 element from pdrgWObjrg
  247. pdrgWObjrg->RemoveFirst();
  248. }
  249. /*
  250. * Subtract from wObjrgTotal all the registered object region counts we
  251. * have removed.
  252. */
  253. wObjrgTotal -= rgwOffset[idfcpLast - idfcpFirst];
  254. // Now we remove the wObjrg of the last FCP in this block from pdrgWObjrg
  255. wObjrgTotal -= *(WORD*) pdrgWObjrg->GetBasePtr();
  256. pdrgWObjrg->RemoveFirst();
  257. _idfcpFirst = idfcpLast + 1;
  258. if (pdrgBrowse) {
  259. ASSERT(ptblBrowse);
  260. if (!fBrowseButtonSet)
  261. VReportError(HCERR_NO_BROWSE_BUTTONS, &errHpj);
  262. // REVIEW: This is not very efficient
  263. QDEBROWSE lpDeBrowse;
  264. while (pdrgBrowse->Count() > 0 &&
  265. (lpDeBrowse = (QDEBROWSE) pdrgBrowse->GetBasePtr())->idfcp <=
  266. idfcpLast) {
  267. int iBitdex;
  268. FCL fcl = (*pfnBrowseCallback) (lpDeBrowse->idfcp, &iBitdex);
  269. pa.objoff = rgwOffset[lpDeBrowse->idfcp - idfcpFirst];
  270. // Print prev/next codes into file:
  271. // szMajor : szMinor : fcl fixup pos : Zeck compression bit dex : PA
  272. char szBuf[200];
  273. ASSERT(strlen(lpDeBrowse->szMajor) + strlen(lpDeBrowse->szMinor) < 170);
  274. wsprintf(szBuf, "%s:%s:%8lX:%8lX:%8lX\n",
  275. lpDeBrowse->szMajor,
  276. lpDeBrowse->szMinor, fcl, iBitdex, *(int *) (&pa));
  277. if (!ptblBrowse->AddString(szBuf))
  278. OOM(); // does not return
  279. lcFree(lpDeBrowse->szMajor);
  280. lcFree(lpDeBrowse->szMinor);
  281. pdrgBrowse->RemoveFirst();
  282. }
  283. }
  284. while (pdrgTitle->Count() > 0 &&
  285. (lpDeTitle = (LPDETITLE) pdrgTitle->GetBasePtr())->idfcp <= idfcpLast) {
  286. pa.objoff = rgwOffset[lpDeTitle->idfcp - idfcpFirst];
  287. #ifdef _DEBUG
  288. {
  289. // Verify that things are sorted correctly. If they aren't,
  290. // RcFillHbt() will create a broken btree.
  291. static ADDR addrLast = addrNil;
  292. ASSERT(addrLast == addrNil || addrLast < *(ADDR *) &pa);
  293. addrLast = *(ADDR *) &pa;
  294. }
  295. #endif // DEBUG
  296. if ((rc = RcFillHbt(fmsg.qbthrTTL, (KEY) &pa, lpDeTitle->szTitle))
  297. != RC_Success)
  298. return rc;
  299. ASSERT(lpDeTitle->szTitle);
  300. lcFree(lpDeTitle->szTitle);
  301. pdrgTitle->RemoveFirst();
  302. }
  303. QDECONTEXT qdectx;
  304. while (pdrgContext->Count() > 0 &&
  305. (qdectx = (QDECONTEXT) pdrgContext->GetBasePtr())->idfcp <=
  306. idfcpLast) {
  307. pa.objoff = rgwOffset[qdectx->idfcp - idfcpFirst] + qdectx->wObjrg;
  308. if ((rc = RcInsertHbt(fmsg.qbthrCtx, (KEY) &qdectx->hash,
  309. (LPVOID) &pa)) != RC_Success && rc != RC_Exists)
  310. return rc;
  311. pdrgContext->RemoveFirst();
  312. }
  313. LPDEKEYWORD pDeKeyword;
  314. while (pdrgKeyword->Count() > 0 &&
  315. (pDeKeyword = (LPDEKEYWORD) pdrgKeyword->GetBasePtr())->idfcp <=
  316. idfcpLast) {
  317. KWD kwd;
  318. pa.objoff = rgwOffset[pDeKeyword->idfcp - idfcpFirst] +
  319. pDeKeyword->wObjrg;
  320. kwd.addr = *(ADDR *)&pa;
  321. for (int iszKey = 1; iszKey <= pDeKeyword->ptbl->CountStrings();
  322. ++iszKey) {
  323. kwd.szKey = pDeKeyword->ptbl->GetPointer(iszKey);
  324. RcWritePkwd(&kwd, pDeKeyword->chKey);
  325. }
  326. delete pDeKeyword->ptbl;
  327. pdrgKeyword->RemoveFirst();
  328. }
  329. return RC_Success;
  330. }