Leaked source code of windows server 2003
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.

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