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.

548 lines
15 KiB

  1. /*** acpins.c - ACPI Name Space functions
  2. *
  3. * Copyright (c) 1996,1997 Microsoft Corporation
  4. * Author: Michael Tsang (MikeTs)
  5. * Created 10/18/96
  6. *
  7. * MODIFICATION HISTORY
  8. */
  9. #include "pch.h"
  10. /***LP InitNameSpace - Initialize NameSpace
  11. *
  12. * ENTRY
  13. * None
  14. *
  15. * EXIT-SUCCESS
  16. * returns ASLERR_NONE
  17. * EXIT-FAILURE
  18. * returns negative error code
  19. */
  20. int LOCAL InitNameSpace(VOID)
  21. {
  22. int rc = ASLERR_NONE;
  23. ENTER((1, "InitNameSpace()\n"));
  24. if ((rc = CreateNameSpaceObj(NULL, "\\", NULL, NULL, NULL, NSF_EXIST_ERR))
  25. == ASLERR_NONE)
  26. {
  27. static struct _defobj {
  28. PSZ pszName;
  29. USHORT dwObjType;
  30. } DefinedRootObjs[] = {
  31. "_GPE", OBJTYPE_UNKNOWN,
  32. "_PR", OBJTYPE_UNKNOWN,
  33. "_SB", OBJTYPE_UNKNOWN,
  34. "_SI", OBJTYPE_UNKNOWN,
  35. "_TZ", OBJTYPE_UNKNOWN,
  36. "_REV", OBJTYPE_INTDATA,
  37. "_OS", OBJTYPE_STRDATA,
  38. "_GL", OBJTYPE_MUTEX,
  39. NULL, 0
  40. };
  41. int i;
  42. PNSOBJ pns;
  43. gpnsCurrentScope = gpnsNameSpaceRoot;
  44. for (i = 0; DefinedRootObjs[i].pszName != NULL; ++i)
  45. {
  46. if ((rc = CreateNameSpaceObj(NULL, DefinedRootObjs[i].pszName, NULL,
  47. NULL, &pns, NSF_EXIST_ERR)) ==
  48. ASLERR_NONE)
  49. {
  50. pns->ObjData.dwDataType = DefinedRootObjs[i].dwObjType;
  51. }
  52. else
  53. {
  54. break;
  55. }
  56. }
  57. }
  58. EXIT((1, "InitNameSpace=%d\n", rc));
  59. return rc;
  60. } //InitNameSpace
  61. /***LP GetNameSpaceObj - Find a name space object
  62. *
  63. * ENTRY
  64. * pszObjPath -> name path string
  65. * pnsScope -> scope to start the search (NULL means root)
  66. * ppns -> to hold the nsobj pointer found
  67. * dwfNS - flags
  68. *
  69. * EXIT-SUCCESS
  70. * returns ASLERR_NONE
  71. * EXIT-FAILURE
  72. * returns negative error code
  73. */
  74. int LOCAL GetNameSpaceObj(PSZ pszObjPath, PNSOBJ pnsScope, PPNSOBJ ppns,
  75. DWORD dwfNS)
  76. {
  77. int rc = ASLERR_NONE;
  78. PSZ psz;
  79. ENTER((1, "GetNameSpaceObj(ObjPath=%s,Scope=%s,ppns=%p,Flags=%x)\n",
  80. pszObjPath, pnsScope? GetObjectPath(pnsScope): "", ppns, dwfNS));
  81. if (pnsScope == NULL)
  82. pnsScope = gpnsNameSpaceRoot;
  83. if (*pszObjPath == '\\')
  84. {
  85. psz = &pszObjPath[1];
  86. pnsScope = gpnsNameSpaceRoot;
  87. }
  88. else
  89. {
  90. psz = pszObjPath;
  91. while ((*psz == '^') && (pnsScope != NULL))
  92. {
  93. psz++;
  94. pnsScope = pnsScope->pnsParent;
  95. }
  96. }
  97. *ppns = pnsScope;
  98. if (pnsScope == NULL)
  99. rc = ASLERR_NSOBJ_NOT_FOUND;
  100. else if (*psz != '\0')
  101. {
  102. BOOL fSearchUp;
  103. PNSOBJ pns;
  104. fSearchUp = !(dwfNS & NSF_LOCAL_SCOPE) &&
  105. (pszObjPath[0] != '\\') &&
  106. (pszObjPath[0] != '^') &&
  107. (strlen(pszObjPath) <= sizeof(NAMESEG));
  108. for (;;)
  109. {
  110. do
  111. {
  112. if ((pns = pnsScope->pnsFirstChild) == NULL)
  113. rc = ASLERR_NSOBJ_NOT_FOUND;
  114. else
  115. {
  116. BOOL fFound;
  117. PSZ pszEnd;
  118. DWORD dwLen;
  119. NAMESEG dwName;
  120. if ((pszEnd = strchr(psz, '.')) != NULL)
  121. dwLen = (DWORD)(pszEnd - psz);
  122. else
  123. dwLen = strlen(psz);
  124. if (dwLen > sizeof(NAMESEG))
  125. {
  126. ERROR(("GetNameSpaceObj: invalid name - %s",
  127. pszObjPath));
  128. rc = ASLERR_INVALID_NAME;
  129. fFound = FALSE;
  130. }
  131. else
  132. {
  133. dwName = NAMESEG_BLANK;
  134. memcpy(&dwName, psz, dwLen);
  135. //
  136. // Search all siblings for a matching NameSeg.
  137. //
  138. fFound = FALSE;
  139. do
  140. {
  141. if (pns->dwNameSeg == dwName)
  142. {
  143. pnsScope = pns;
  144. fFound = TRUE;
  145. break;
  146. }
  147. pns = (PNSOBJ)pns->list.plistNext;
  148. } while (pns != pns->pnsParent->pnsFirstChild);
  149. }
  150. if (rc == ASLERR_NONE)
  151. {
  152. if (!fFound)
  153. rc = ASLERR_NSOBJ_NOT_FOUND;
  154. else
  155. {
  156. psz += dwLen;
  157. if (*psz == '.')
  158. {
  159. psz++;
  160. }
  161. else if (*psz == '\0')
  162. {
  163. *ppns = pnsScope;
  164. break;
  165. }
  166. }
  167. }
  168. }
  169. } while (rc == ASLERR_NONE);
  170. if ((rc == ASLERR_NSOBJ_NOT_FOUND) && fSearchUp &&
  171. (pnsScope != NULL) && (pnsScope->pnsParent != NULL))
  172. {
  173. pnsScope = pnsScope->pnsParent;
  174. rc = ASLERR_NONE;
  175. }
  176. else
  177. {
  178. break;
  179. }
  180. }
  181. }
  182. if (rc != ASLERR_NONE)
  183. {
  184. *ppns = NULL;
  185. }
  186. EXIT((1, "GetNameSpaceObj=%d (pns=%p)\n", rc, *ppns));
  187. return rc;
  188. } //GetNameSpaceObj
  189. /***LP CreateNameSpaceObj - Create a name space object under current scope
  190. *
  191. * ENTRY
  192. * ptoken -> TOKEN
  193. * pszName -> name path string
  194. * pnsScope -> scope to start the search (NULL means root)
  195. * pnsOwner -> owner object
  196. * ppns -> to hold the nsobj pointer found
  197. * dwfNS - flags
  198. *
  199. * EXIT-SUCCESS
  200. * returns ASLERR_NONE
  201. * EXIT-FAILURE
  202. * returns negative error code
  203. */
  204. int LOCAL CreateNameSpaceObj(PTOKEN ptoken, PSZ pszName, PNSOBJ pnsScope,
  205. PNSOBJ pnsOwner, PPNSOBJ ppns, DWORD dwfNS)
  206. {
  207. int rc = ASLERR_NONE;
  208. PNSOBJ pns;
  209. #ifndef _UNASM_LIB
  210. char szMsg[MAX_MSG_LEN + 1];
  211. #endif
  212. ENTER((1, "CreateNameSpaceObj(ptoken=%p,Name=%s,pnsScope=%s,pnsOwner=%p,ppns=%p,Flags=%x)\n",
  213. ptoken, pszName, pnsScope? GetObjectPath(pnsScope): "", pnsOwner,
  214. ppns, dwfNS));
  215. #ifdef _UNASM_LIB
  216. DEREF(ptoken);
  217. #endif
  218. ASSERT((pszName != NULL) && (*pszName != '\0'));
  219. if (pnsScope == NULL)
  220. pnsScope = gpnsNameSpaceRoot;
  221. if ((rc = GetNameSpaceObj(pszName, pnsScope, &pns, NSF_LOCAL_SCOPE)) ==
  222. ASLERR_NONE)
  223. {
  224. if (!(dwfNS & NSF_EXIST_OK))
  225. {
  226. #ifndef _UNASM_LIB
  227. if (ptoken != NULL)
  228. {
  229. sprintf(szMsg, "%s already exist", pszName);
  230. PrintTokenErr(ptoken, szMsg, dwfNS & NSF_EXIST_ERR);
  231. }
  232. else
  233. {
  234. ERROR(("%s: error: %s already exist",
  235. gpszASLFile? gpszASLFile: gpszAMLFile, pszName));
  236. }
  237. #endif
  238. rc = ASLERR_NSOBJ_EXIST;
  239. }
  240. }
  241. else if (rc == ASLERR_NSOBJ_NOT_FOUND)
  242. {
  243. rc = ASLERR_NONE;
  244. //
  245. // Are we creating root?
  246. //
  247. if (strcmp(pszName, "\\") == 0)
  248. {
  249. ASSERT(gpnsNameSpaceRoot == NULL);
  250. ASSERT(pnsOwner == NULL);
  251. if ((pns = MEMALLOC(sizeof(NSOBJ))) == NULL)
  252. {
  253. ERROR(("CreateNameSpaceObj: fail to allocate name space object"));
  254. rc = ASLERR_OUT_OF_MEM;
  255. }
  256. else
  257. {
  258. memset(pns, 0, sizeof(NSOBJ));
  259. pns->dwNameSeg = NAMESEG_ROOT;
  260. pns->hOwner = (HANDLE)pnsOwner;
  261. gpnsNameSpaceRoot = pns;
  262. }
  263. }
  264. else
  265. {
  266. PSZ psz;
  267. PNSOBJ pnsParent;
  268. if ((psz = strrchr(pszName, '.')) != NULL)
  269. {
  270. *psz = '\0';
  271. psz++;
  272. if ((rc = GetNameSpaceObj(pszName, pnsScope, &pnsParent,
  273. NSF_LOCAL_SCOPE)) ==
  274. ASLERR_NSOBJ_NOT_FOUND)
  275. {
  276. #ifndef _UNASM_LIB
  277. if (ptoken != NULL)
  278. {
  279. sprintf(szMsg, "parent object %s does not exist",
  280. pszName);
  281. PrintTokenErr(ptoken, szMsg, TRUE);
  282. }
  283. else
  284. {
  285. ERROR(("%s: error: parent object %s does not exist",
  286. gpszASLFile? gpszASLFile: gpszAMLFile, pszName));
  287. }
  288. #endif
  289. }
  290. }
  291. else if (*pszName == '\\')
  292. {
  293. psz = &pszName[1];
  294. //
  295. // By this time, we'd better created root already.
  296. //
  297. ASSERT(gpnsNameSpaceRoot != NULL);
  298. pnsParent = gpnsNameSpaceRoot;
  299. }
  300. else if (*pszName == '^')
  301. {
  302. psz = pszName;
  303. pnsParent = pnsScope;
  304. while ((*psz == '^') && (pnsParent != NULL))
  305. {
  306. pnsParent = pnsParent->pnsParent;
  307. psz++;
  308. }
  309. }
  310. else
  311. {
  312. ASSERT(pnsScope != NULL);
  313. psz = pszName;
  314. pnsParent = pnsScope;
  315. }
  316. if (rc == ASLERR_NONE)
  317. {
  318. int iLen = strlen(psz);
  319. if ((*psz != '\0') && (iLen > sizeof(NAMESEG)))
  320. {
  321. ERROR(("CreateNameSpaceObj: invalid name - %s", psz));
  322. rc = ASLERR_INVALID_NAME;
  323. }
  324. else if ((pns = MEMALLOC(sizeof(NSOBJ))) == NULL)
  325. {
  326. ERROR(("CreateNameSpaceObj: fail to allocate name space object"));
  327. rc = ASLERR_OUT_OF_MEM;
  328. }
  329. else
  330. {
  331. memset(pns, 0, sizeof(NSOBJ));
  332. pns->dwNameSeg = NAMESEG_BLANK;
  333. memcpy(&(pns->dwNameSeg), psz, iLen);
  334. pns->hOwner = (HANDLE)pnsOwner;
  335. pns->pnsParent = pnsParent;
  336. ListInsertTail(&pns->list,
  337. (PPLIST)&pnsParent->pnsFirstChild);
  338. }
  339. }
  340. }
  341. }
  342. if ((rc == ASLERR_NONE) && (ppns != NULL))
  343. *ppns = pns;
  344. EXIT((1, "CreateNameSpaceObj=%d (pns=%p)\n", rc, pns));
  345. return rc;
  346. } //CreateNameSpaceObj
  347. /***LP DumpNameSpacePaths - Dump all the name space object paths
  348. *
  349. * ENTRY
  350. * pnsObj -> name space subtree root
  351. * pfileOut -> output device
  352. *
  353. * EXIT
  354. * None
  355. */
  356. VOID LOCAL DumpNameSpacePaths(PNSOBJ pnsObj, FILE *pfileOut)
  357. {
  358. PNSOBJ pns, pnsNext;
  359. ENTER((3, "DumpNameSpacePaths(pns=%x,pfileOut=%p)\n", pnsObj, pfileOut));
  360. //
  361. // First, dump myself
  362. //
  363. fprintf(pfileOut, "%13s: [%08x] %s",
  364. GetObjectTypeName(pnsObj->ObjData.dwDataType), pnsObj->dwRefCount,
  365. GetObjectPath(pnsObj));
  366. if (pnsObj->ObjData.dwDataType == OBJTYPE_METHOD)
  367. {
  368. fprintf(pfileOut, " (cArgs=%d)", pnsObj->ObjData.uipDataValue);
  369. }
  370. else if (pnsObj->ObjData.dwDataType == OBJTYPE_RES_FIELD)
  371. {
  372. fprintf(pfileOut, " (BitOffset=0x%x, BitSize=0x%x)",
  373. pnsObj->ObjData.uipDataValue, pnsObj->ObjData.dwDataLen);
  374. }
  375. fprintf(pfileOut, "%s\n", pnsObj->hOwner? "*": "");
  376. //
  377. // Then, recursively dump each of my children
  378. //
  379. for (pns = pnsObj->pnsFirstChild; pns != NULL; pns = pnsNext)
  380. {
  381. //
  382. // If this is the last child, we have no more.
  383. //
  384. if ((pnsNext = (PNSOBJ)pns->list.plistNext) == pnsObj->pnsFirstChild)
  385. pnsNext = NULL;
  386. //
  387. // Dump a child
  388. //
  389. DumpNameSpacePaths(pns, pfileOut);
  390. }
  391. EXIT((3, "DumpNameSpacePaths!\n"));
  392. } //DumpNameSpacePaths
  393. /***LP GetObjectPath - get object namespace path
  394. *
  395. * ENTRY
  396. * pns -> object
  397. *
  398. * EXIT
  399. * returns name space path
  400. */
  401. PSZ LOCAL GetObjectPath(PNSOBJ pns)
  402. {
  403. static char szPath[MAX_NSPATH_LEN + 1] = {0};
  404. int i;
  405. ENTER((4, "GetObjectPath(pns=%x)\n", pns));
  406. if (pns != NULL)
  407. {
  408. if (pns->pnsParent == NULL)
  409. strcpy(szPath, "\\");
  410. else
  411. {
  412. GetObjectPath(pns->pnsParent);
  413. if (pns->pnsParent->pnsParent != NULL)
  414. {
  415. strcat(szPath, ".");
  416. }
  417. strncat(szPath, (PSZ)&pns->dwNameSeg, sizeof(NAMESEG));
  418. }
  419. for (i = strlen(szPath) - 1; i >= 0; --i)
  420. {
  421. if (szPath[i] == '_')
  422. szPath[i] = '\0';
  423. else
  424. break;
  425. }
  426. }
  427. else
  428. {
  429. szPath[0] = '\0';
  430. }
  431. EXIT((4, "GetObjectPath=%s\n", szPath));
  432. return szPath;
  433. } //GetObjectPath
  434. /***LP GetObjectTypeName - get object type name
  435. *
  436. * ENTRY
  437. * dwObjType - object type
  438. *
  439. * EXIT
  440. * return object type name
  441. */
  442. PSZ LOCAL GetObjectTypeName(DWORD dwObjType)
  443. {
  444. PSZ psz = NULL;
  445. int i;
  446. static struct
  447. {
  448. ULONG dwObjType;
  449. PSZ pszObjTypeName;
  450. } ObjTypeTable[] =
  451. {
  452. OBJTYPE_UNKNOWN, "Unknown",
  453. OBJTYPE_INTDATA, "Integer",
  454. OBJTYPE_STRDATA, "String",
  455. OBJTYPE_BUFFDATA, "Buffer",
  456. OBJTYPE_PKGDATA, "Package",
  457. OBJTYPE_FIELDUNIT, "FieldUnit",
  458. OBJTYPE_DEVICE, "Device",
  459. OBJTYPE_EVENT, "Event",
  460. OBJTYPE_METHOD, "Method",
  461. OBJTYPE_MUTEX, "Mutex",
  462. OBJTYPE_OPREGION, "OpRegion",
  463. OBJTYPE_POWERRES, "PowerResource",
  464. OBJTYPE_PROCESSOR, "Processor",
  465. OBJTYPE_THERMALZONE,"ThermalZone",
  466. OBJTYPE_BUFFFIELD, "BuffField",
  467. OBJTYPE_DDBHANDLE, "DDBHandle",
  468. OBJTYPE_DEBUG, "Debug",
  469. OBJTYPE_OBJALIAS, "ObjAlias",
  470. OBJTYPE_DATAALIAS, "DataAlias",
  471. OBJTYPE_BANKFIELD, "BankField",
  472. OBJTYPE_FIELD, "Field",
  473. OBJTYPE_INDEXFIELD, "IndexField",
  474. OBJTYPE_DATA, "Data",
  475. OBJTYPE_DATAFIELD, "DataField",
  476. OBJTYPE_DATAOBJ, "DataObject",
  477. OBJTYPE_PNP_RES, "PNPResource",
  478. OBJTYPE_RES_FIELD, "ResField",
  479. 0, NULL
  480. };
  481. ENTER((4, "GetObjectTypeName(Type=%x)\n", dwObjType));
  482. for (i = 0; ObjTypeTable[i].pszObjTypeName != NULL; ++i)
  483. {
  484. if (dwObjType == ObjTypeTable[i].dwObjType)
  485. {
  486. psz = ObjTypeTable[i].pszObjTypeName;
  487. break;
  488. }
  489. }
  490. EXIT((4, "GetObjectTypeName=%s\n", psz? psz: "NULL"));
  491. return psz;
  492. } //GetObjectTypeName