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.

1009 lines
26 KiB

  1. /*** misc.c - Miscellaneous functions
  2. *
  3. * Copyright (c) 1996,1997 Microsoft Corporation
  4. * Author: Michael Tsang (MikeTs)
  5. * Created: 10/14/96
  6. *
  7. * MODIFICATION HISTORY
  8. */
  9. #include "aslp.h"
  10. /***LP ValidASLNameSeg - Check if the token is an ASL NameSeg
  11. *
  12. * ENTRY
  13. * ptoken - token stream
  14. * pszToken -> token string
  15. * icbLen - length of the token to be considered a NameSeg
  16. *
  17. * EXIT-SUCCESS
  18. * returns TRUE
  19. * EXIT-FAILURE
  20. * returns FALSE
  21. */
  22. BOOL LOCAL ValidASLNameSeg(PTOKEN ptoken, PSZ pszToken, int icbLen)
  23. {
  24. BOOL rc = TRUE;
  25. int i, j;
  26. static PSZ apszReservedNames[] = {
  27. "ADR", "ALN", "BAS", "BBN", "BCL", "BCM", "BDN", "BIF", "BM_", "BST",
  28. "BTP", "CID", "CRS", "CRT", "DCK", "DCS", "DDC", "DDN", "DEC", "DGS",
  29. "DIS", "DMA", "DOD", "DOS", "DSS", "EC_", "EJD", "FDE", "FDI", "GL_",
  30. "GLK", "GPE", "GRA", "GTF", "GTM", "HE_", "HID", "INI", "INT", "IRC",
  31. "LCK", "LEN", "LID", "LL_", "MAF", "MAX", "MEM", "MIF", "MIN", "MSG",
  32. "OFF", "ON_", "OS_", "PCL", "PIC", "PR_", "PRS", "PRT", "PRW", "PSC",
  33. "PSL", "PSR", "PSV", "PSW", "PTS", "PWR", "REG", "REV", "RMV", "RNG",
  34. "ROM", "RQ_", "RW_", "SB_", "SBS", "SCP", "SHR", "SI_", "SIZ", "SRS",
  35. "SST", "STA", "STM", "SUN", "TC1", "TC2", "TMP", "TRA", "TSP", "TYP",
  36. "TZ_", "UID", "WAK", "AC0", "AC1", "AC2", "AC3", "AC4", "AC5", "AC6",
  37. "AC7", "AC8", "AC9", "AL0", "AL1", "AL2", "AL3", "AL4", "AL5", "AL6",
  38. "AL7", "AL8", "AL9", "EC0", "EC1", "EC2", "EC3", "EC4", "EC5", "EC6",
  39. "EC7", "EC7", "EC9", "EJ0", "EJ1", "EJ2", "EJ3", "EJ4",
  40. "Exx", "Lxx", "Qxx",
  41. "S0_", "S1_", "S2_", "S3_", "S4_", "S5_",
  42. "S0D", "S1D", "S2D", "S3D", "S4D", "S5D",
  43. "PR0", "PR1", "PR2",
  44. "PS0", "PS1", "PS2", "PS3"
  45. };
  46. #define NUM_RESERVED_NAMES (sizeof(apszReservedNames)/sizeof(PSZ))
  47. ENTER((1, "ValidASLNameSeg(ptoken=%p, Token=%s,Len=%d)\n",
  48. ptoken, pszToken, icbLen));
  49. pszToken[0] = (char)toupper(pszToken[0]);
  50. if ((icbLen > sizeof(NAMESEG)) || !ISLEADNAMECHAR(pszToken[0]))
  51. {
  52. rc = FALSE;
  53. }
  54. else
  55. {
  56. for (i = 1; i < icbLen; ++i)
  57. {
  58. pszToken[i] = (char)toupper(pszToken[i]);
  59. if (!ISNAMECHAR(pszToken[i]))
  60. {
  61. rc = FALSE;
  62. break;
  63. }
  64. }
  65. if ((rc == TRUE) && (*pszToken == '_'))
  66. {
  67. char szName[sizeof(NAMESEG)] = "___";
  68. memcpy(szName, &pszToken[1], icbLen - 1);
  69. for (i = 0; i < NUM_RESERVED_NAMES; ++i)
  70. {
  71. if (strcmp(szName, apszReservedNames[i]) == 0)
  72. break;
  73. else
  74. {
  75. for (j = 0; j < sizeof(NAMESEG) - 1; ++j)
  76. {
  77. if (apszReservedNames[i][j] != szName[j])
  78. {
  79. if ((apszReservedNames[i][j] != 'x') ||
  80. !isxdigit(szName[j]))
  81. {
  82. break;
  83. }
  84. }
  85. }
  86. if (j == sizeof(NAMESEG) - 1)
  87. {
  88. break;
  89. }
  90. }
  91. }
  92. if (i == NUM_RESERVED_NAMES)
  93. {
  94. PrintTokenErr(ptoken, "not a valid reserved NameSeg", FALSE);
  95. }
  96. }
  97. }
  98. EXIT((1, "ValidASLNameSeg=%d\n", rc));
  99. return rc;
  100. } //ValidASLNameSeg
  101. /***LP ValidASLName - Check if the token is an ASL name
  102. *
  103. * ENTRY
  104. * ptoken - token stream
  105. * pszToken -> token string
  106. *
  107. * EXIT-SUCCESS
  108. * returns TRUE
  109. * EXIT-FAILURE
  110. * returns FALSE
  111. */
  112. BOOL LOCAL ValidASLName(PTOKEN ptoken, PSZ pszToken)
  113. {
  114. BOOL rc = TRUE;
  115. PSZ psz1, psz2 = NULL;
  116. int icbLen;
  117. ENTER((1, "ValidASLName(ptoken=%p,Token=%s)\n", ptoken, pszToken));
  118. if (*pszToken == CH_ROOT_PREFIX)
  119. {
  120. pszToken++;
  121. }
  122. else
  123. {
  124. while (*pszToken == CH_PARENT_PREFIX)
  125. {
  126. pszToken++;
  127. }
  128. }
  129. for (psz1 = pszToken;
  130. (rc == TRUE) && (psz1 != NULL) && (*psz1 != '\0');
  131. psz1 = psz2)
  132. {
  133. psz2 = strchr(psz1, CH_NAMESEG_SEP);
  134. icbLen = (psz2 != NULL)? (int)(psz2 - psz1): strlen(psz1);
  135. if (((rc = ValidASLNameSeg(ptoken, psz1, icbLen)) == TRUE) &&
  136. (psz2 != NULL))
  137. {
  138. psz2++;
  139. }
  140. }
  141. EXIT((1, "ValidASLName=%d\n", rc));
  142. return rc;
  143. } //ValidASLName
  144. /***LP EncodeName - Encode name string
  145. *
  146. * ENTRY
  147. * pszName -> name string
  148. * pbBuff -> buffer to hold name encoding
  149. * pdwLen -> initially contains buffer size, but will be updated to show
  150. * actual encoding length
  151. *
  152. * EXIT-SUCCESS
  153. * returns ASLERR_NONE
  154. * EXIT-FAILURE
  155. * returns negative error code
  156. */
  157. int LOCAL EncodeName(PSZ pszName, PBYTE pbBuff, PDWORD pdwLen)
  158. {
  159. int rc = ASLERR_NONE;
  160. PBYTE pb = pbBuff;
  161. PSZ psz;
  162. int icNameSegs, i;
  163. ENTER((1, "EncodeName(Name=%s,pbBuff=%p,Len=%d)\n",
  164. pszName, pbBuff, *pdwLen));
  165. if (*pszName == CH_ROOT_PREFIX)
  166. {
  167. if (*pdwLen >= 1)
  168. {
  169. *pb = OP_ROOT_PREFIX;
  170. pb++;
  171. (*pdwLen)--;
  172. pszName++;
  173. }
  174. else
  175. rc = ASLERR_NAME_TOO_LONG;
  176. }
  177. else
  178. {
  179. while (*pszName == CH_PARENT_PREFIX)
  180. {
  181. if (*pdwLen >= 1)
  182. {
  183. *pb = OP_PARENT_PREFIX;
  184. pb++;
  185. (*pdwLen)--;
  186. pszName++;
  187. }
  188. else
  189. {
  190. rc = ASLERR_NAME_TOO_LONG;
  191. break;
  192. }
  193. }
  194. }
  195. for (psz = pszName, icNameSegs = 0; (psz != NULL) && (*psz != '\0');)
  196. {
  197. icNameSegs++;
  198. if ((psz = strchr(psz, CH_NAMESEG_SEP)) != NULL)
  199. psz++;
  200. }
  201. if (icNameSegs > 255)
  202. rc = ASLERR_NAME_TOO_LONG;
  203. else if (icNameSegs > 2)
  204. {
  205. if (*pdwLen >= sizeof(NAMESEG)*icNameSegs + 2)
  206. {
  207. *pb = OP_MULTI_NAME_PREFIX;
  208. pb++;
  209. *pb = (BYTE)icNameSegs;
  210. pb++;
  211. }
  212. else
  213. rc = ASLERR_NAME_TOO_LONG;
  214. }
  215. else if (icNameSegs == 2)
  216. {
  217. if (*pdwLen >= sizeof(NAMESEG)*2 + 1)
  218. {
  219. *pb = OP_DUAL_NAME_PREFIX;
  220. pb++;
  221. }
  222. else
  223. rc = ASLERR_NAME_TOO_LONG;
  224. }
  225. if (rc == ASLERR_NONE)
  226. {
  227. //
  228. // If we have only name prefix characters, we must put a null name
  229. // separator to tell the boundary from the next opcode which may happen
  230. // to be a NameSeg.
  231. //
  232. if (icNameSegs == 0)
  233. {
  234. *pb = 0;
  235. pb++;
  236. }
  237. else
  238. {
  239. while (icNameSegs > 0)
  240. {
  241. *((PDWORD)pb) = NAMESEG_BLANK;
  242. for (i = 0;
  243. (i < sizeof(NAMESEG)) && ISNAMECHAR(*pszName);
  244. ++i, pszName++)
  245. {
  246. pb[i] = *pszName;
  247. }
  248. if (*pszName == CH_NAMESEG_SEP)
  249. pszName++;
  250. pb += 4;
  251. icNameSegs--;
  252. }
  253. }
  254. *pdwLen = (DWORD)(pb - pbBuff);
  255. }
  256. EXIT((1, "EncodeName=%d (Len=%d)\n", rc, *pdwLen));
  257. return rc;
  258. } //EncodeName
  259. /***LP EncodePktLen - Encode packet length
  260. *
  261. * ENTRY
  262. * dwCodeLen - actual code length
  263. * pdwPktLen -> to hold the encoded packet length
  264. * picbEncoding -> to hold the number of encoding bytes
  265. *
  266. * EXIT-SUCCESS
  267. * returns ASLERR_NONE
  268. * EXIT-FAILURE
  269. * returns negative error code
  270. */
  271. int LOCAL EncodePktLen(DWORD dwCodeLen, PDWORD pdwPktLen, PINT picbEncoding)
  272. {
  273. int rc = ASLERR_NONE;
  274. ENTER((1, "EncodePktLen(CodeLen=%ld,pdwPktLen=%p)\n",
  275. dwCodeLen, pdwPktLen));
  276. if (dwCodeLen <= 0x3f)
  277. {
  278. *pdwPktLen = dwCodeLen;
  279. *picbEncoding = 1;
  280. }
  281. else
  282. {
  283. *pdwPktLen = (dwCodeLen & 0x0ffffff0) << 4;
  284. *pdwPktLen |= (dwCodeLen & 0xf);
  285. if (dwCodeLen <= 0x0fff)
  286. *picbEncoding = 2;
  287. else if (dwCodeLen <= 0x0fffff)
  288. *picbEncoding = 3;
  289. else if (dwCodeLen <= 0x0fffffff)
  290. *picbEncoding = 4;
  291. else
  292. rc = ASLERR_PKTLEN_TOO_LONG;
  293. if (rc == ASLERR_NONE)
  294. *pdwPktLen |= (*picbEncoding - 1) << 6;
  295. }
  296. EXIT((1, "EncodePktLen=%d (Encoding=%lx,icbEncoding=%d)\n",
  297. rc, *pdwPktLen, *picbEncoding));
  298. return rc;
  299. } //EncodePktLen
  300. /***LP EncodeKeywords - Encode keyword arguments
  301. *
  302. * ENTRY
  303. * pArgs -> argument array
  304. * dwSrcArgs - source argument bit vector
  305. * iDstArgNum - destination argument number
  306. *
  307. * EXIT
  308. * None
  309. */
  310. VOID LOCAL EncodeKeywords(PCODEOBJ pArgs, DWORD dwSrcArgs, int iDstArgNum)
  311. {
  312. int i;
  313. DWORD dwData = 0;
  314. ENTER((1, "EncodeKeywords(pArgs=%p,SrcArgs=%lx,DstArgNum=%d)\n",
  315. pArgs, dwSrcArgs, iDstArgNum));
  316. for (i = 0; i < MAX_ARGS; ++i)
  317. {
  318. if (dwSrcArgs & (1 << i))
  319. {
  320. if (pArgs[i].dwCodeType == CODETYPE_KEYWORD)
  321. {
  322. dwData |= TermTable[pArgs[i].dwTermIndex].dwTermData & 0xff;
  323. }
  324. else if (pArgs[i].dwCodeType == CODETYPE_INTEGER)
  325. {
  326. pArgs[i].dwCodeType = CODETYPE_UNKNOWN;
  327. dwData |= pArgs[i].dwCodeValue;
  328. }
  329. else
  330. {
  331. ASSERT(pArgs[i].dwCodeType == CODETYPE_INTEGER);
  332. }
  333. }
  334. }
  335. SetIntObject(&pArgs[iDstArgNum], dwData, sizeof(BYTE));
  336. EXIT((1, "EncodeKeywords!\n"));
  337. } //EncodeKeywords
  338. /***LP DecodeName - Decode name encoding back to a name string
  339. *
  340. * ENTRY
  341. * pb -> name encoding buffer
  342. * pszName -> to hold the decoded name string
  343. * iLen - length of name string buffer
  344. *
  345. * EXIT-SUCCESS
  346. * returns ASLERR_NONE
  347. * EXIT-FAILURE
  348. * returns negative error code
  349. */
  350. int LOCAL DecodeName(PBYTE pb, PSZ pszName, int iLen)
  351. {
  352. int rc = ASLERR_NONE;
  353. int i = 0, icNameSegs;
  354. ENTER((1, "DecodeName(pb=%p,pszName=%p,iLen=%d)\n", pb, pszName, iLen));
  355. iLen--; //reserve one space for NULL character
  356. pszName[iLen] = '\0';
  357. if (*pb == OP_ROOT_PREFIX)
  358. {
  359. if (i < iLen)
  360. {
  361. pszName[i] = CH_ROOT_PREFIX;
  362. i++;
  363. pb++;
  364. }
  365. else
  366. rc = ASLERR_NAME_TOO_LONG;
  367. }
  368. while (*pb == OP_PARENT_PREFIX)
  369. {
  370. if (i < iLen)
  371. {
  372. pszName[i] = CH_PARENT_PREFIX;
  373. i++;
  374. pb++;
  375. }
  376. else
  377. rc = ASLERR_NAME_TOO_LONG;
  378. }
  379. if (*pb == OP_DUAL_NAME_PREFIX)
  380. {
  381. icNameSegs = 2;
  382. pb++;
  383. }
  384. else if (*pb == OP_MULTI_NAME_PREFIX)
  385. {
  386. pb++;
  387. icNameSegs = (int)(*pb);
  388. pb++;
  389. }
  390. else if (*pb == 0)
  391. {
  392. icNameSegs = 0;
  393. }
  394. else
  395. {
  396. icNameSegs = 1;
  397. }
  398. if (icNameSegs > 0)
  399. {
  400. do
  401. {
  402. if ((int)(i + sizeof(NAMESEG)) <= iLen)
  403. {
  404. strncpy(&pszName[i], (PCHAR)pb, sizeof(NAMESEG));
  405. pb += sizeof(NAMESEG);
  406. i += sizeof(NAMESEG);
  407. icNameSegs--;
  408. if (icNameSegs > 0)
  409. {
  410. if (i < iLen)
  411. {
  412. pszName[i] = CH_NAMESEG_SEP;
  413. i++;
  414. }
  415. else
  416. rc = ASLERR_NAME_TOO_LONG;
  417. }
  418. }
  419. else
  420. rc = ASLERR_NAME_TOO_LONG;
  421. } while ((rc == ASLERR_NONE) && (icNameSegs > 0));
  422. }
  423. if (rc == ASLERR_NONE)
  424. pszName[i] = '\0';
  425. else
  426. {
  427. ERROR(("DecodeName: Name is too long - %s", pszName));
  428. }
  429. EXIT((1, "DecodeName=%d (Name=%s)\n", rc, pszName));
  430. return rc;
  431. } //DecodeName
  432. /***LP SetDefMissingKW - Set default missing keyword
  433. *
  434. * ENTRY
  435. * pArg -> argument code object
  436. * dwDefID - default ID to be used if argument is missing
  437. *
  438. * EXIT-SUCCESS
  439. * returns ASLERR_NONE
  440. * EXIT-FAILURE
  441. * returns negative error code
  442. */
  443. int LOCAL SetDefMissingKW(PCODEOBJ pArg, DWORD dwDefID)
  444. {
  445. int rc = ASLERR_NONE;
  446. ENTER((2, "SetDefMissingKW(pArg=%p,ID=%d)\n", pArg, dwDefID));
  447. if (pArg->dwfCode & CF_MISSING_ARG)
  448. {
  449. pArg->dwfCode &= ~CF_MISSING_ARG;
  450. pArg->dwCodeType = CODETYPE_KEYWORD;
  451. pArg->dwCodeValue = dwDefID;
  452. rc = LookupIDIndex(pArg->dwCodeValue, &pArg->dwTermIndex);
  453. }
  454. EXIT((2, "SetDefMissingKW=%d (TermIndex=%ld)\n", rc, pArg->dwTermIndex));
  455. return rc;
  456. } //SetDefMissingKW
  457. /***LP SetIntObject - Set an object to type integer
  458. *
  459. * ENTRY
  460. * pc -> object
  461. * dwData - integer data
  462. * dwLen - data length
  463. *
  464. * EXIT
  465. * None
  466. */
  467. VOID LOCAL SetIntObject(PCODEOBJ pc, DWORD dwData, DWORD dwLen)
  468. {
  469. ENTER((2, "SetIntObject(pc=%p,Data=%x,Len=%d)\n", pc, dwData, dwLen));
  470. pc->dwCodeType = CODETYPE_INTEGER;
  471. pc->dwCodeValue = dwData;
  472. pc->dwDataLen = pc->dwCodeLen = dwLen;
  473. pc->bCodeChkSum = ComputeDataChkSum((PBYTE)&dwData, dwLen);
  474. EXIT((2, "SetIntObject!\n"));
  475. } //SetIntObject
  476. /***LP ComputeChildChkSumLen - Compute len and chksum of child for parent
  477. *
  478. * ENTRY
  479. * pcParent -> code block of parent
  480. * pcChild -> code block of child
  481. *
  482. * EXIT
  483. * None
  484. */
  485. VOID LOCAL ComputeChildChkSumLen(PCODEOBJ pcParent, PCODEOBJ pcChild)
  486. {
  487. ENTER((1, "ComputeChildChkSumLen(pcParent=%p,pcChild=%p,ChildLen=%ld,ChildChkSum=%x)\n",
  488. pcParent, pcChild, pcChild->dwCodeLen, pcChild->bCodeChkSum));
  489. pcParent->dwCodeLen += pcChild->dwCodeLen;
  490. pcParent->bCodeChkSum = (BYTE)(pcParent->bCodeChkSum +
  491. pcChild->bCodeChkSum);
  492. if (pcChild->dwCodeType == CODETYPE_ASLTERM)
  493. {
  494. int i;
  495. for (i = 0; i < OPCODELEN(pcChild->dwCodeValue); ++i)
  496. {
  497. pcParent->bCodeChkSum = (BYTE)(pcParent->bCodeChkSum +
  498. ((PBYTE)(&pcChild->dwCodeValue))[i]);
  499. pcParent->dwCodeLen++;
  500. }
  501. }
  502. EXIT((1, "ComputeChildChkSumLen! (Len=%ld,ChkSum=%x)\n",
  503. pcParent->dwCodeLen, pcParent->bCodeChkSum));
  504. } //ComputeChildChkSumLen
  505. /***LP ComputeArgsChkSumLen - Compute length and checksum of arguments
  506. *
  507. * ENTRY
  508. * pcode -> code block
  509. *
  510. * EXIT
  511. * None
  512. */
  513. VOID LOCAL ComputeArgsChkSumLen(PCODEOBJ pcode)
  514. {
  515. PCODEOBJ pc;
  516. int i;
  517. ENTER((1, "ComputeArgsChkSumLen(pcode=%p)\n", pcode));
  518. ASSERT((pcode->dwCodeType == CODETYPE_ASLTERM) ||
  519. (pcode->dwCodeType == CODETYPE_USERTERM));
  520. //
  521. // Sum the length of arguments
  522. //
  523. for (i = 0, pc = (PCODEOBJ)pcode->pbDataBuff;
  524. i < (int)pcode->dwDataLen;
  525. ++i)
  526. {
  527. ComputeChildChkSumLen(pcode, &pc[i]);
  528. }
  529. EXIT((1, "ComputeArgsChkSumLen! (Len=%ld,ChkSum=%x)\n",
  530. pcode->dwCodeLen, pcode->bCodeChkSum));
  531. } //ComputeArgsChkSumLen
  532. /***LP ComputeChkSumLen - Compute length and checksum of code block
  533. *
  534. * Compute the length of the given code block and store it in the dwCodeLen
  535. * field of the code block.
  536. * Compute the checksum of the given code block and store it in the
  537. * bCodeChkSum field of the code block.
  538. *
  539. * ENTRY
  540. * pcode -> code block
  541. *
  542. * EXIT
  543. * None
  544. *
  545. * NOTE
  546. * This function does not count the opcode length of the given ASLTERM.
  547. * The caller is responsible for adding it if necessary.
  548. */
  549. VOID LOCAL ComputeChkSumLen(PCODEOBJ pcode)
  550. {
  551. PCODEOBJ pc;
  552. int i, j;
  553. ENTER((1, "ComputeChkSumLen(pcode=%p)\n", pcode));
  554. ASSERT(pcode->dwCodeType == CODETYPE_ASLTERM);
  555. if (!(TermTable[pcode->dwTermIndex].dwfTermClass & TC_COMPILER_DIRECTIVE))
  556. {
  557. ComputeArgsChkSumLen(pcode);
  558. }
  559. //
  560. // Sum the lengths of children
  561. //
  562. for (pc = pcode->pcFirstChild; pc != NULL;)
  563. {
  564. ComputeChildChkSumLen(pcode, pc);
  565. if ((PCODEOBJ)pc->list.plistNext == pcode->pcFirstChild)
  566. pc = NULL;
  567. else
  568. pc = (PCODEOBJ)pc->list.plistNext;
  569. }
  570. //
  571. // If this term requires a PkgLength encoding, we must include it in the
  572. // length.
  573. //
  574. if (TermTable[pcode->dwTermIndex].dwfTerm & TF_PACKAGE_LEN)
  575. {
  576. DWORD dwPktLen;
  577. if (pcode->dwCodeLen <= 0x3f - 1)
  578. pcode->dwCodeLen++;
  579. else if (pcode->dwCodeLen <= 0xfff - 2)
  580. pcode->dwCodeLen += 2;
  581. else if (pcode->dwCodeLen <= 0xfffff - 3)
  582. pcode->dwCodeLen += 3;
  583. else
  584. pcode->dwCodeLen += 4;
  585. if (EncodePktLen(pcode->dwCodeLen, &dwPktLen, &j) == ASLERR_NONE)
  586. {
  587. for (i = 0; i < j; ++i)
  588. {
  589. pcode->bCodeChkSum = (BYTE)(pcode->bCodeChkSum +
  590. ((PBYTE)&dwPktLen)[i]);
  591. }
  592. }
  593. }
  594. EXIT((1, "ComputeChkSumLen! (len=%ld,ChkSum=%x)\n",
  595. pcode->dwCodeLen, pcode->bCodeChkSum));
  596. } //ComputeChkSumLen
  597. /***LP ComputeDataChkSum - Compute checksum of a data buffer
  598. *
  599. * ENTRY
  600. * pb -> data buffer
  601. * dwLen - size of data buffer
  602. *
  603. * EXIT
  604. * returns the checksum byte
  605. */
  606. BYTE LOCAL ComputeDataChkSum(PBYTE pb, DWORD dwLen)
  607. {
  608. BYTE bChkSum = 0;
  609. ENTER((1, "ComputeDataChkSum(pb=%p,Len=%ld)\n", pb, dwLen));
  610. while (dwLen > 0)
  611. {
  612. bChkSum = (BYTE)(bChkSum + *pb);
  613. pb++;
  614. dwLen--;
  615. }
  616. EXIT((1, "ComputeDataChkSum=%x\n", bChkSum));
  617. return bChkSum;
  618. } //ComputeChkSumLen
  619. /***LP ComputeEISAID - Compute EISA ID from the ID string
  620. *
  621. * ENTRY
  622. * pszID -> ID string
  623. * pdwEISAID -> to hold the EISA ID
  624. *
  625. * EXIT-SUCCESS
  626. * returns ASLERR_NONE
  627. * EXIT-FAILURE
  628. * returns negative error code
  629. */
  630. int LOCAL ComputeEISAID(PSZ pszID, PDWORD pdwEISAID)
  631. {
  632. int rc = ASLERR_NONE;
  633. ENTER((1, "ComputeEISAID(pszID=%s,pdwEISAID=%p)\n", pszID, pdwEISAID));
  634. if (*pszID == '*')
  635. pszID++;
  636. if (strlen(pszID) != 7)
  637. rc = ASLERR_INVALID_EISAID;
  638. else
  639. {
  640. int i;
  641. *pdwEISAID = 0;
  642. for (i = 0; i < 3; ++i)
  643. {
  644. if ((pszID[i] < '@') || (pszID[i] > '_'))
  645. {
  646. rc = ASLERR_INVALID_EISAID;
  647. break;
  648. }
  649. else
  650. {
  651. (*pdwEISAID) <<= 5;
  652. (*pdwEISAID) |= pszID[i] - '@';
  653. }
  654. }
  655. if (rc == ASLERR_NONE)
  656. {
  657. PSZ psz;
  658. WORD wData;
  659. (*pdwEISAID) = ((*pdwEISAID & 0x00ff) << 8) |
  660. ((*pdwEISAID & 0xff00) >> 8);
  661. wData = (WORD)strtoul(&pszID[3], &psz, 16);
  662. if (*psz != '\0')
  663. {
  664. rc = ASLERR_INVALID_EISAID;
  665. }
  666. else
  667. {
  668. wData = (WORD)(((wData & 0x00ff) << 8) |
  669. ((wData & 0xff00) >> 8));
  670. (*pdwEISAID) |= (DWORD)wData << 16;
  671. }
  672. }
  673. }
  674. EXIT((1, "ComputeEISAID=%d (EISAID=%lx)\n", rc, *pdwEISAID));
  675. return rc;
  676. } //ComputeEISAID
  677. /***LP LookupIDIndex - lookup the given ID in the TermTable and return index
  678. *
  679. * ENTRY
  680. * lID - ID to look up
  681. * pdwTermIndex -> to hold term index found
  682. *
  683. * EXIT-SUCCESS
  684. * returns ASLERR_NONE
  685. * EXIT-FAILURE
  686. * returns negative error code
  687. */
  688. int LOCAL LookupIDIndex(LONG lID, PDWORD pdwTermIndex)
  689. {
  690. int rc = ASLERR_NONE;
  691. int i;
  692. ENTER((1, "LookupIDIndex(ID=%ld,pdwTermIndex=%p)\n", lID, pdwTermIndex));
  693. for (i = 0; TermTable[i].pszID != NULL; ++i)
  694. {
  695. if (lID == TermTable[i].lID)
  696. {
  697. *pdwTermIndex = (DWORD)i;
  698. break;
  699. }
  700. }
  701. if (TermTable[i].pszID == NULL)
  702. {
  703. ERROR(("LookupIDIndex: failed to find ID %ld in TermTable", lID));
  704. rc = ASLERR_INTERNAL_ERROR;
  705. }
  706. EXIT((1, "LookupIDIndex=%d (Index=%d)\n", rc, *pdwTermIndex));
  707. return rc;
  708. } //LookupIDIndex
  709. /***LP WriteAMLFile - Write code block to AML file
  710. *
  711. * ENTRY
  712. * fhAML - AML image file handle
  713. * pcode -> code block
  714. * pdwOffset -> file offset
  715. *
  716. * EXIT-SUCCESS
  717. * returns ASLERR_NONE
  718. * EXIT-FAILURE
  719. * returns negative error code
  720. */
  721. int LOCAL WriteAMLFile(int fhAML, PCODEOBJ pcode, PDWORD pdwOffset)
  722. {
  723. int rc = ASLERR_NONE;
  724. int iLen;
  725. DWORD dwPktLen, dwLen;
  726. ENTER((1, "WriteAMLFile(fhAML=%x,pcode=%p,FileOffset=%x)\n",
  727. fhAML, pcode, *pdwOffset));
  728. if (pcode->dwfCode & CF_CREATED_NSOBJ)
  729. {
  730. ASSERT(pcode->pnsObj != NULL);
  731. ASSERT(pcode->pnsObj->dwRefCount == 0);
  732. pcode->pnsObj->dwRefCount = *pdwOffset;
  733. }
  734. switch (pcode->dwCodeType)
  735. {
  736. case CODETYPE_ASLTERM:
  737. if (pcode->dwCodeValue != OP_NONE)
  738. {
  739. iLen = OPCODELEN(pcode->dwCodeValue);
  740. *pdwOffset += iLen;
  741. if (_write(fhAML, &pcode->dwCodeValue, iLen) != iLen)
  742. rc = ASLERR_WRITE_FILE;
  743. else if (TermTable[pcode->dwTermIndex].dwfTerm & TF_PACKAGE_LEN)
  744. {
  745. if ((rc = EncodePktLen(pcode->dwCodeLen, &dwPktLen, &iLen))
  746. == ASLERR_NONE)
  747. {
  748. *pdwOffset += iLen;
  749. if (_write(fhAML, &dwPktLen, iLen) != iLen)
  750. {
  751. rc = ASLERR_WRITE_FILE;
  752. }
  753. }
  754. }
  755. if (rc == ASLERR_NONE)
  756. {
  757. if (pcode->pbDataBuff != NULL)
  758. {
  759. PCODEOBJ pc;
  760. int i;
  761. for (i = 0, pc = (PCODEOBJ)pcode->pbDataBuff;
  762. i < (int)pcode->dwDataLen;
  763. ++i)
  764. {
  765. if ((rc = WriteAMLFile(fhAML, &pc[i], pdwOffset))
  766. != ASLERR_NONE)
  767. {
  768. break;
  769. }
  770. }
  771. }
  772. }
  773. }
  774. if (rc == ASLERR_NONE)
  775. {
  776. PCODEOBJ pc;
  777. for (pc = pcode->pcFirstChild; pc != NULL;)
  778. {
  779. if ((rc = WriteAMLFile(fhAML, pc, pdwOffset)) !=
  780. ASLERR_NONE)
  781. {
  782. break;
  783. }
  784. if ((PCODEOBJ)pc->list.plistNext ==
  785. pcode->pcFirstChild)
  786. {
  787. pc = NULL;
  788. }
  789. else
  790. pc = (PCODEOBJ)pc->list.plistNext;
  791. }
  792. }
  793. break;
  794. case CODETYPE_USERTERM:
  795. if (pcode->pbDataBuff != NULL)
  796. {
  797. PCODEOBJ pc;
  798. int i;
  799. for (i = 0, pc = (PCODEOBJ)pcode->pbDataBuff;
  800. i < (int)pcode->dwDataLen;
  801. ++i)
  802. {
  803. if ((rc = WriteAMLFile(fhAML, &pc[i], pdwOffset)) !=
  804. ASLERR_NONE)
  805. {
  806. break;
  807. }
  808. }
  809. }
  810. break;
  811. case CODETYPE_FIELDOBJ:
  812. dwPktLen = pcode->dwCodeValue? sizeof(NAMESEG): sizeof(BYTE);
  813. dwLen = ((pcode->dwDataLen & 0xc0) >> 6) + 1;
  814. *pdwOffset += dwPktLen + dwLen;
  815. if ((_write(fhAML, &pcode->dwCodeValue, dwPktLen) !=
  816. (int)dwPktLen) ||
  817. (_write(fhAML, &pcode->dwDataLen, dwLen) != (int)dwLen))
  818. {
  819. rc = ASLERR_WRITE_FILE;
  820. }
  821. break;
  822. case CODETYPE_NAME:
  823. case CODETYPE_DATAOBJ:
  824. *pdwOffset += pcode->dwDataLen;
  825. if (_write(fhAML, pcode->pbDataBuff, (int)pcode->dwDataLen) !=
  826. (int)pcode->dwDataLen)
  827. {
  828. rc = ASLERR_WRITE_FILE;
  829. }
  830. break;
  831. case CODETYPE_INTEGER:
  832. *pdwOffset += pcode->dwDataLen;
  833. if (_write(fhAML, &pcode->dwCodeValue, (int)pcode->dwDataLen) !=
  834. (int)pcode->dwDataLen)
  835. {
  836. rc = ASLERR_WRITE_FILE;
  837. }
  838. break;
  839. case CODETYPE_UNKNOWN:
  840. case CODETYPE_KEYWORD:
  841. break;
  842. default:
  843. ERROR(("WriteAMLFile: unexpected code type - %x",
  844. pcode->dwCodeType));
  845. rc = ASLERR_INTERNAL_ERROR;
  846. }
  847. EXIT((1, "WriteAMLFile=%d\n", rc));
  848. return rc;
  849. } //WriteAMLFile
  850. /***LP FreeCodeObjs - free code object tree
  851. *
  852. * ENTRY
  853. * pcodeRoot -> root of code object subtree to be free
  854. *
  855. * EXIT
  856. * None
  857. */
  858. VOID LOCAL FreeCodeObjs(PCODEOBJ pcodeRoot)
  859. {
  860. PCODEOBJ pcode, pcodeNext;
  861. ENTER((1, "FreeCodeObjs(pcodeRoot=%p,Type=%d,Term=%s,Buff=%p)\n",
  862. pcodeRoot, pcodeRoot->dwCodeType,
  863. pcodeRoot->dwCodeType == CODETYPE_ASLTERM?
  864. TermTable[pcodeRoot->dwTermIndex].pszID: "<null>",
  865. pcodeRoot->pbDataBuff));
  866. //
  867. // Free all my children
  868. //
  869. for (pcode = pcodeRoot->pcFirstChild; pcode != NULL; pcode = pcodeNext)
  870. {
  871. if ((pcodeNext = (PCODEOBJ)pcode->list.plistNext) ==
  872. pcodeRoot->pcFirstChild)
  873. {
  874. pcodeNext = NULL;
  875. }
  876. FreeCodeObjs(pcode);
  877. }
  878. if (pcodeRoot->pbDataBuff != NULL)
  879. MEMFREE(pcodeRoot->pbDataBuff);
  880. MEMFREE(pcodeRoot);
  881. EXIT((1, "FreeCodeObjs!\n"));
  882. } //FreeCodeObjs