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.

1685 lines
50 KiB

  1. /*** amliapi.c - AMLI APIs
  2. *
  3. * Copyright (c) 1996,1997 Microsoft Corporation
  4. * Author: Michael Tsang (MikeTs)
  5. * Created 08/13/96
  6. *
  7. * MODIFICATION HISTORY
  8. */
  9. #include "pch.h"
  10. //#include "amlihook.h"
  11. //#include "amlitest.h"
  12. #ifdef LOCKABLE_PRAGMA
  13. #pragma ACPI_LOCKABLE_DATA
  14. #pragma ACPI_LOCKABLE_CODE
  15. #endif
  16. /*++
  17. OSIAML contains the AML for the _OSI Method. This AML is generated from the following ASL:
  18. Method(_OSI, 0x1, NotSerialized)
  19. {
  20. Return(OSI(Arg0))
  21. }
  22. --*/
  23. UCHAR OSIAML[] = {
  24. 0xa4, 0xca, 0x68
  25. };
  26. /***EP AMLIInitialize - Initialize AML interpreter
  27. *
  28. * @DOC EXTERNAL
  29. *
  30. * @FUNC NTSTATUS | AMLIInitialize | AML Interpreter initialization.
  31. *
  32. * This function must be called before any AML interpreter functions
  33. * can be called. This function will typically allocate and
  34. * initialize global resources, create the ACPI name space etc.
  35. * It is typically called in the initialization of the ACPI core
  36. * driver.
  37. *
  38. * @PARM ULONG | dwCtxtBlkSize | Specifies the size of Context blocks. If
  39. * zero, use default context block size.
  40. *
  41. * @PARM ULONG | dwGlobalHeapBlkSize | Specifies the size of Global heap.
  42. * If zero, use default global heap size.
  43. *
  44. * @PARM ULONG | dwfAMLIInit | AMLI initialization flags.
  45. *
  46. * @FLAG AMLIIF_INIT_BREAK | Break into the debugger at initialization
  47. * completion.
  48. *
  49. * @FLAG AMLIIF_LOADDDB_BREAK | Break into the debugger at load definition
  50. * block completion.
  51. *
  52. * @PARM ULONG | dwmsTimeSliceLength | Time slice length in msec.
  53. *
  54. * @PARM ULONG | dwmsTimeSliceInterval | Time slice interval in msec.
  55. *
  56. * @PARM ULONG | dwmsMaxCTObjs | Number of context to allocate
  57. *
  58. * @RDESC SUCCESS - Returns STATUS_SUCCESS.
  59. *
  60. * @RDESC FAILURE - Returns NT status code.
  61. */
  62. NTSTATUS AMLIAPI AMLIInitialize(ULONG dwCtxtBlkSize, ULONG dwGlobalHeapBlkSize,
  63. ULONG dwfAMLIInit, ULONG dwmsTimeSliceLength,
  64. ULONG dwmsTimeSliceInterval, ULONG dwmsMaxCTObjs)
  65. {
  66. TRACENAME("AMLIINITIALIZE")
  67. NTSTATUS rc = STATUS_SUCCESS;
  68. ENTER(1, ("AMLIInitialize(InitFlags=%x,CtxtBlkSize=%d,GlobalHeapBlkSize=%d,TimeSliceLen=%d,TimeSliceInterval=%d)\n",
  69. dwfAMLIInit, dwCtxtBlkSize, dwGlobalHeapBlkSize,
  70. dwmsTimeSliceLength, dwmsTimeSliceInterval));
  71. #ifndef DEBUGGER
  72. DEREF(dwfAMLIInit);
  73. #endif
  74. RESETERR();
  75. if (gpnsNameSpaceRoot != NULL)
  76. {
  77. rc = AMLI_LOGERR(AMLIERR_ALREADY_INITIALIZED,
  78. ("AMLIInitialize: interpreter already initialized"));
  79. }
  80. else
  81. {
  82. gdwCtxtBlkSize = dwCtxtBlkSize ? dwCtxtBlkSize: DEF_CTXTBLK_SIZE;
  83. gdwGlobalHeapBlkSize = dwGlobalHeapBlkSize? dwGlobalHeapBlkSize:
  84. DEF_GLOBALHEAPBLK_SIZE;
  85. gdwfAMLIInit = dwfAMLIInit;
  86. gdwfHacks = GetHackFlags(NULL);
  87. //
  88. // Sanity Check
  89. //
  90. if (dwmsMaxCTObjs > 1024) {
  91. dwmsMaxCTObjs = 1024;
  92. }
  93. gdwcCTObjsMax = (dwmsMaxCTObjs > DEF_CTXTMAX_SIZE) ? dwmsMaxCTObjs :
  94. DEF_CTXTMAX_SIZE;
  95. #ifdef DEBUGGER
  96. // gDebugger.dwfDebugger |= (DBGF_LOGEVENT_ON | DBGF_ERRBREAK_ON);
  97. gDebugger.dwfDebugger |= DBGF_LOGEVENT_ON;
  98. SetLogSize(DEF_MAXLOG_ENTRIES);
  99. KeInitializeSpinLock( &gdwGHeapSpinLock );
  100. #endif
  101. KeInitializeSpinLock( &gdwGContextSpinLock );
  102. //
  103. // Initialize the LookAside lists.
  104. //
  105. ExInitializeNPagedLookasideList(
  106. &AMLIContextLookAsideList,
  107. NULL,
  108. NULL,
  109. 0,
  110. gdwCtxtBlkSize,
  111. CTOBJ_TAG,
  112. (USHORT) gdwcCTObjsMax
  113. );
  114. if ((rc = NewHeap(gdwGlobalHeapBlkSize, &gpheapGlobal)) ==
  115. STATUS_SUCCESS)
  116. {
  117. int i;
  118. PNSOBJ pns;
  119. static PSZ apszDefinedRootObjs[] =
  120. {
  121. "_GPE", "_PR", "_SB", "_SI", "_TZ"
  122. };
  123. #define NUM_DEFINED_ROOT_OBJS (sizeof(apszDefinedRootObjs)/sizeof(PSZ))
  124. gpheapGlobal->pheapHead = gpheapGlobal;
  125. if ((rc = CreateNameSpaceObject(gpheapGlobal, NAMESTR_ROOT, NULL,
  126. NULL, NULL, 0)) == STATUS_SUCCESS)
  127. {
  128. for (i = 0; i < NUM_DEFINED_ROOT_OBJS; ++i)
  129. {
  130. if ((rc = CreateNameSpaceObject(gpheapGlobal,
  131. apszDefinedRootObjs[i],
  132. NULL, NULL, NULL, 0)) !=
  133. STATUS_SUCCESS)
  134. {
  135. break;
  136. }
  137. }
  138. }
  139. if ((rc == STATUS_SUCCESS) &&
  140. ((rc = CreateNameSpaceObject(gpheapGlobal, "_REV", NULL, NULL,
  141. &pns, 0)) == STATUS_SUCCESS))
  142. {
  143. pns->ObjData.dwDataType = OBJTYPE_INTDATA;
  144. pns->ObjData.uipDataValue = AMLI_REVISION;
  145. }
  146. if ((rc == STATUS_SUCCESS) &&
  147. ((rc = CreateNameSpaceObject(gpheapGlobal, "_OS", NULL, NULL,
  148. &pns, 0)) == STATUS_SUCCESS))
  149. {
  150. pns->ObjData.dwDataType = OBJTYPE_STRDATA;
  151. pns->ObjData.dwDataLen = STRLEN(gpszOSName) + 1;
  152. if ((pns->ObjData.pbDataBuff = NEWSDOBJ(gpheapGlobal,
  153. pns->ObjData.dwDataLen))
  154. == NULL)
  155. {
  156. rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  157. ("AMLIInitialize: failed to allocate \\_OS name object"));
  158. }
  159. else
  160. {
  161. MEMCPY(pns->ObjData.pbDataBuff, gpszOSName,
  162. pns->ObjData.dwDataLen);
  163. }
  164. }
  165. if ((rc == STATUS_SUCCESS) &&
  166. ((rc = CreateNameSpaceObject(gpheapGlobal,"_OSI", NULL, NULL,
  167. &pns, 0)) == STATUS_SUCCESS))
  168. {
  169. pns->ObjData.dwDataType = OBJTYPE_METHOD;
  170. pns->ObjData.dwDataLen = sizeof(METHODOBJ) + sizeof(OSIAML) - sizeof(UCHAR);
  171. if ((pns->ObjData.pbDataBuff = NEWSDOBJ(gpheapGlobal,
  172. pns->ObjData.dwDataLen))
  173. == NULL)
  174. {
  175. rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  176. ("AMLIInitiaize: failed to allocate \\_OSI name object"));
  177. }
  178. else
  179. {
  180. MEMZERO(pns->ObjData.pbDataBuff, pns->ObjData.dwDataLen);
  181. //This method has one argument
  182. ((PMETHODOBJ)(pns->ObjData.pbDataBuff))->bMethodFlags |= 0x1;
  183. MEMCPY(((PMETHODOBJ)(pns->ObjData.pbDataBuff))->abCodeBuff, (PUCHAR)OSIAML,
  184. sizeof(OSIAML));
  185. }
  186. }
  187. if ((rc == STATUS_SUCCESS) &&
  188. ((rc = CreateNameSpaceObject(gpheapGlobal, "_GL", NULL, NULL,
  189. &pns, 0)) == STATUS_SUCCESS))
  190. {
  191. pns->ObjData.dwfData = DATAF_GLOBAL_LOCK;
  192. rc = InitMutex(gpheapGlobal, pns, 0);
  193. }
  194. if (rc == STATUS_SUCCESS)
  195. {
  196. gReadyQueue.dwmsTimeSliceLength = dwmsTimeSliceLength?
  197. dwmsTimeSliceLength:
  198. DEF_TIMESLICE_LENGTH;
  199. gReadyQueue.dwmsTimeSliceInterval = dwmsTimeSliceInterval?
  200. dwmsTimeSliceInterval:
  201. DEF_TIMESLICE_INTERVAL;
  202. KeInitializeTimer(&gReadyQueue.Timer);
  203. InitializeMutex(&gReadyQueue.mutCtxtQ);
  204. ExInitializeWorkItem(&gReadyQueue.WorkItem,
  205. StartTimeSlicePassive, &gReadyQueue);
  206. InitializeMutex(&gmutCtxtList);
  207. InitializeMutex(&gmutOwnerList);
  208. InitializeMutex(&gmutHeap);
  209. InitializeMutex(&gmutSleep);
  210. KeInitializeDpc(&gReadyQueue.DpcStartTimeSlice,
  211. StartTimeSlice,
  212. &gReadyQueue);
  213. KeInitializeDpc(&gReadyQueue.DpcExpireTimeSlice,
  214. ExpireTimeSlice,
  215. &gReadyQueue);
  216. KeInitializeDpc(&SleepDpc, SleepQueueDpc, NULL);
  217. KeInitializeTimer(&SleepTimer);
  218. InitializeListHead(&SleepQueue);
  219. InitializeRegOverrideFlags();
  220. InitIllegalIOAddressListFromHAL();
  221. }
  222. }
  223. }
  224. if (rc == AMLISTA_PENDING)
  225. rc = STATUS_PENDING;
  226. else if (rc != STATUS_SUCCESS)
  227. rc = NTERR(rc);
  228. #ifdef DEBUGGER
  229. if (gdwfAMLIInit & AMLIIF_INIT_BREAK)
  230. {
  231. PRINTF("\n" MODNAME ": Break at AMLI Initialization Completion.\n");
  232. AMLIDebugger(FALSE);
  233. }
  234. #endif
  235. EXIT(1, ("AMLIInitialize=%x\n", rc));
  236. return rc;
  237. } //AMLIInitialize
  238. /***EP AMLITerminate - Terminate AML interpreter
  239. *
  240. * @DOC EXTERNAL
  241. *
  242. * @FUNC NTSTATUS | AMLITerminate | AML Interpreter termination.
  243. *
  244. * This function is called to clean up all the global resources used
  245. * by the AML interpreter.
  246. *
  247. * @RDESC SUCCESS - Returns STATUS_SUCCESS.
  248. *
  249. * @RDESC FAILURE - Returns NT status code.
  250. */
  251. NTSTATUS AMLIAPI AMLITerminate(VOID)
  252. {
  253. TRACENAME("AMLITERMINATE")
  254. NTSTATUS rc = STATUS_SUCCESS;
  255. ENTER(1, ("AMLITerminate()\n"));
  256. RESETERR();
  257. if (gpnsNameSpaceRoot == NULL)
  258. {
  259. rc = AMLI_LOGERR(AMLIERR_NOT_INITIALIZED,
  260. ("AMLITerminate: interpreter not initialized"));
  261. }
  262. else
  263. {
  264. PLIST plist;
  265. PHEAP pheap;
  266. #ifdef DEBUGGER
  267. FreeSymList();
  268. if (gDebugger.pEventLog != NULL)
  269. {
  270. MFREE(gDebugger.pEventLog);
  271. }
  272. MEMZERO(&gDebugger, sizeof(DBGR));
  273. #endif
  274. ASSERT(gReadyQueue.pkthCurrent == NULL);
  275. ASSERT(gReadyQueue.pctxtCurrent == NULL);
  276. FreeNameSpaceObjects(gpnsNameSpaceRoot);
  277. gpnsNameSpaceRoot = NULL;
  278. MEMZERO(&gReadyQueue, sizeof(CTXTQ));
  279. while ((plist = ListRemoveTail(&gplistCtxtHead)) != NULL)
  280. {
  281. FreeContext(CONTAINING_RECORD(plist, CTXT, listCtxt));
  282. }
  283. while ((plist = ListRemoveTail(&gplistObjOwners)) != NULL)
  284. {
  285. FreeObjOwner((POBJOWNER)plist, FALSE);
  286. }
  287. while ((plist = ListRemoveTail(&gplistDefuncNSObjs)) != NULL)
  288. {
  289. FREENSOBJ(CONTAINING_RECORD(plist, NSOBJ, list));
  290. }
  291. FreeRSAccessList(gpRSAccessHead);
  292. gpRSAccessHead = NULL;
  293. MEMZERO(&ghNotify, sizeof(EVHANDLE));
  294. MEMZERO(&ghValidateTable, sizeof(EVHANDLE));
  295. MEMZERO(&ghFatal, sizeof(EVHANDLE));
  296. MEMZERO(&ghGlobalLock, sizeof(EVHANDLE));
  297. MEMZERO(&ghCreate, sizeof(EVHANDLE));
  298. MEMZERO(&ghDestroyObj,sizeof(EVHANDLE));
  299. for (pheap = gpheapGlobal; pheap != NULL; pheap = gpheapGlobal)
  300. {
  301. gpheapGlobal = pheap->pheapNext;
  302. FreeHeap(pheap);
  303. }
  304. FreellegalIOAddressList();
  305. gdwfAMLI = 0;
  306. #ifdef DEBUG
  307. if (gdwcMemObjs != 0)
  308. {
  309. DumpMemObjCounts();
  310. ASSERT(gdwcMemObjs == 0);
  311. }
  312. #endif
  313. }
  314. if (rc == AMLISTA_PENDING)
  315. rc = STATUS_PENDING;
  316. else if (rc != STATUS_SUCCESS)
  317. rc = NTERR(rc);
  318. EXIT(1, ("AMLITerminate=%x\n", rc));
  319. return rc;
  320. } //AMLITerminate
  321. /***EP AMLILoadDDB - Load and parse Differentiated Definition Block
  322. *
  323. * @DOC EXTERNAL
  324. *
  325. * @FUNC NTSTATUS | AMLILoadDDB | Load Differentiated Definition Block.
  326. *
  327. * This function loads and parses the given Differentiated System
  328. * Description Table as well as any dynamic Differentiated Definition
  329. * Block. It will parse the DDB and populate the ACPI name space
  330. * accordingly.
  331. *
  332. * @PARM PDSDT | pDSDT | Pointer to a DSDT block.
  333. *
  334. * @PARM HANDLE * | phDDB | Pointer to the variable that will receive
  335. * the DDB handle (can be NULL).
  336. *
  337. * @RDESC SUCCESS - Returns STATUS_SUCCESS.
  338. *
  339. * @RDESC FAILURE - Returns NT status code if encountering parse error.
  340. *
  341. * @DEVNOTE If an error occurs in the middle of loading a DDB, the loading
  342. * will be aborted but the objects created prior to the error remain
  343. * in the name space. Therefore, it is the responsibility of the
  344. * caller to call AMLIUnLoadDDB to destroy the created objects if
  345. * desired and the return handle is not NULL.
  346. */
  347. NTSTATUS AMLIAPI AMLILoadDDB(PDSDT pDSDT, HANDLE *phDDB)
  348. {
  349. TRACENAME("AMLILOADDDB")
  350. NTSTATUS rc = STATUS_SUCCESS;
  351. PCTXT pctxt = NULL;
  352. POBJOWNER powner = NULL;
  353. ENTER(1, ("AMLILoadDDB(pDSDT=%x,phDDB=%x)\n", pDSDT, phDDB));
  354. ASSERT(pDSDT != NULL);
  355. RESETERR();
  356. CHKDEBUGGERREQ();
  357. gInitTime = TRUE;
  358. #ifdef DEBUGGER
  359. if (gDebugger.dwfDebugger & DBGF_VERBOSE_ON)
  360. {
  361. PRINTF(MODNAME ": %p: Loading Definition Block %s at 0x%p.\n",
  362. KeGetCurrentThread(), NameSegString(pDSDT->Header.Signature),
  363. pDSDT);
  364. }
  365. #endif
  366. gdwfHacks |= GetHackFlags(pDSDT);
  367. if ((rc = NewContext(&pctxt)) == STATUS_SUCCESS)
  368. {
  369. ASSERT(gpheapGlobal != NULL);
  370. pctxt->pheapCurrent = gpheapGlobal;
  371. #ifdef DEBUG
  372. gdwfAMLI |= AMLIF_LOADING_DDB;
  373. #endif
  374. if (atLoad.pfnCallBack != NULL && atLoad.dwfOpcode & OF_CALLBACK_EX) {
  375. ((PFNOPEX)atLoad.pfnCallBack)(
  376. EVTYPE_OPCODE_EX,
  377. OPEXF_NOTIFY_PRE,
  378. atLoad.dwOpcode,
  379. NULL,
  380. atLoad.dwCBData
  381. );
  382. }
  383. rc = LoadDDB(pctxt,pDSDT, gpnsNameSpaceRoot, &powner);
  384. if (rc == STATUS_SUCCESS)
  385. {
  386. rc = SyncLoadDDB(pctxt);
  387. }
  388. #ifdef DEBUG
  389. {
  390. KIRQL oldIrql;
  391. gdwfAMLI &= ~AMLIF_LOADING_DDB;
  392. KeAcquireSpinLock( &gdwGHeapSpinLock, &oldIrql );
  393. gdwGHeapSnapshot = gdwGlobalHeapSize;
  394. KeReleaseSpinLock( &gdwGHeapSpinLock, oldIrql );
  395. }
  396. #endif
  397. }
  398. if (phDDB != NULL)
  399. {
  400. *phDDB = (HANDLE)powner;
  401. }
  402. if ((powner != NULL) && (atLoad.pfnCallBack != NULL))
  403. {
  404. if (atLoad.dwfOpcode & OF_CALLBACK_EX) {
  405. ((PFNOPEX)atLoad.pfnCallBack)(
  406. EVTYPE_OPCODE_EX,
  407. OPEXF_NOTIFY_POST,
  408. atLoad.dwOpcode,
  409. NULL,
  410. atLoad.dwCBData
  411. );
  412. } else {
  413. atLoad.pfnCallBack(
  414. EVTYPE_OPCODE,
  415. atLoad.dwOpcode,
  416. NULL,
  417. atLoad.dwCBData
  418. );
  419. }
  420. }
  421. #ifdef DEBUGGER
  422. if (gdwfAMLIInit & AMLIIF_LOADDDB_BREAK)
  423. {
  424. PRINTF("\n" MODNAME ": Break at Load Definition Block Completion.\n");
  425. AMLIDebugger(FALSE);
  426. }
  427. #endif
  428. if (rc == AMLISTA_PENDING)
  429. rc = STATUS_PENDING;
  430. else if (rc != STATUS_SUCCESS)
  431. rc = NTERR(rc);
  432. gInitTime = FALSE;
  433. EXIT(1, ("AMLILoadDDB=%x (powner=%x)\n", rc, powner));
  434. return rc;
  435. } //AMLILoadDDB
  436. /***EP AMLIUnloadDDB - Unload Differentiated Definition Block
  437. *
  438. * @DOC EXTERNAL
  439. *
  440. * @FUNC VOID | AMLIUnloadDDB | Unload the Differentiated Definition Block.
  441. *
  442. * This function is called to unload the given dynamic DDB object and
  443. * clean it out of the name space. Note that this function does not
  444. * differentiate between a DSDT from a dynamic DDB, so it is the
  445. * caller's responsibility to not freeing the DSDT accidentally.
  446. *
  447. * @PARM HANDLE | hDDB | handle to the definition block context to be
  448. * unloaded.
  449. *
  450. * @RDESC None.
  451. */
  452. VOID AMLIAPI AMLIUnloadDDB(HANDLE hDDB)
  453. {
  454. TRACENAME("AMLIUNLOADDDB")
  455. ENTER(1, ("AMLIUnloadDDB(hDDB=%x)\n", hDDB));
  456. RESETERR();
  457. if (hDDB != NULL)
  458. {
  459. ASSERT(((POBJOWNER)hDDB)->dwSig == SIG_OBJOWNER);
  460. UnloadDDB((POBJOWNER)hDDB);
  461. }
  462. EXIT(1, ("AMLIUnloadDDB!\n"));
  463. } //AMLIUnloadDDB
  464. /***EP AMLIGetNameSpaceObject - Find a name space object
  465. *
  466. * @DOC EXTERNAL
  467. *
  468. * @FUNC NTSTATUS | AMLIGetNameSpaceObject | Find an object in the ACPI
  469. * name space.
  470. *
  471. * This function accepts an absolute object path as well as a
  472. * relative object path in the form of an ASCIIZ string.
  473. * It will search through the name space in the appropriate
  474. * scope for the given object path and returns the object
  475. * pointer when it is found.
  476. *
  477. * @PARM PSZ | pszObjPath | Pointer to an ASCIIZ string specifying the
  478. * object path.
  479. *
  480. * @PARM PNSOBJ | pnsScope | If not NULL, this points to the object scope
  481. * where the search starts. If pszObjPath is specifying an absolute
  482. * path, this parameter is ignored.
  483. *
  484. * @PARM PPNSOBJ | ppns | Pointer to a variable to hold the object
  485. * point.
  486. *
  487. * @PARM ULONG | dwfFlags | Option flags.
  488. *
  489. * @FLAG NSF_LOCAL_SCOPE | Search local scope only.
  490. *
  491. * @RDESC SUCCESS - Returns STATUS_SUCCESS.
  492. *
  493. * @RDESC FAILURE - Returns NT status code.
  494. */
  495. NTSTATUS AMLIAPI AMLIGetNameSpaceObject(PSZ pszObjPath, PNSOBJ pnsScope,
  496. PPNSOBJ ppns, ULONG dwfFlags)
  497. {
  498. TRACENAME("AMLIGETNAMESPACEOBJECT")
  499. NTSTATUS rc = STATUS_SUCCESS;
  500. PAMLIHOOK_DATA pHData = NULL;
  501. ENTER(1, ("AMLIGetNameSpaceObject(ObjPath=%s,Scope=%s,ppns=%p,Flags=%x)\n",
  502. pszObjPath, GetObjectPath(pnsScope), ppns, dwfFlags));
  503. ASSERT(pszObjPath != NULL);
  504. ASSERT(*pszObjPath != '\0');
  505. ASSERT(ppns != NULL);
  506. RESETERR();
  507. CHKDEBUGGERREQ();
  508. if(IsAmliHookEnabled())
  509. {
  510. rc = AMLITest_Pre_GetNameSpaceObject(
  511. pszObjPath,pnsScope,ppns,dwfFlags,&pHData);
  512. if(rc != STATUS_SUCCESS)
  513. return(rc);
  514. }
  515. if ((pnsScope != NULL) && (pnsScope->ObjData.dwfData & DATAF_NSOBJ_DEFUNC))
  516. {
  517. AMLI_WARN(("AMLIGetNameSpaceObject: pnsScope is no longer valid"));
  518. rc = STATUS_NO_SUCH_DEVICE;
  519. }
  520. else
  521. {
  522. ASSERT((pnsScope == NULL) || !(pnsScope->ObjData.dwfData & DATAF_NSOBJ_DEFUNC));
  523. rc = GetNameSpaceObject(pszObjPath, pnsScope, ppns, dwfFlags);
  524. }
  525. if (rc == AMLISTA_PENDING)
  526. rc = STATUS_PENDING;
  527. else if (rc != STATUS_SUCCESS)
  528. rc = NTERR(rc);
  529. if(IsAmliHookEnabled())
  530. {
  531. rc = AMLITest_Post_GetNameSpaceObject(
  532. &pHData,rc);
  533. }
  534. EXIT(1, ("AMLIGetNameSpaceObject=%x (pns=%p)\n", rc, *ppns));
  535. return rc;
  536. } //AMLIGetNameSpaceObject
  537. /***EP AMLIGetFieldUnitRegionObj - Get OpRegion associated with FieldUnit
  538. *
  539. * @DOC EXTERNAL
  540. *
  541. * @FUNC NTSTATUS | AMLIGetFieldUnitRegionObj | Get the OperationRegion
  542. * object associated with the FieldUnit object.
  543. *
  544. * @PARM PFIELDUNITOBJ | pfu | Pointer to a FieldUnit object.
  545. *
  546. * @PARM PPNSOBJ | ppns | Pointer to a variable to hold the OperationRegion
  547. * object.
  548. *
  549. * @RDESC SUCCESS - Returns STATUS_SUCCESS.
  550. *
  551. * @RDESC FAILURE - Returns NT status code.
  552. */
  553. NTSTATUS AMLIAPI AMLIGetFieldUnitRegionObj(PFIELDUNITOBJ pfu, PPNSOBJ ppns)
  554. {
  555. TRACENAME("AMLIGETFIELDUNITREGIONOBJ")
  556. NTSTATUS rc = STATUS_SUCCESS;
  557. PAMLIHOOK_DATA pHData = NULL;
  558. ENTER(1, ("AMLIGetFieldUnitRegionObj(pfu=%x,ppns=%x)\n", pfu, ppns));
  559. ASSERT(pfu != NULL);
  560. ASSERT(ppns != NULL);
  561. RESETERR();
  562. if(IsAmliHookEnabled())
  563. {
  564. rc = AMLITest_Pre_GetFieldUnitRegionObj(
  565. pfu,ppns,&pHData);
  566. if(rc != STATUS_SUCCESS)
  567. return(rc);
  568. }
  569. rc = GetFieldUnitRegionObj(pfu, ppns);
  570. if (rc != STATUS_SUCCESS)
  571. rc = NTERR(rc);
  572. if(IsAmliHookEnabled())
  573. {
  574. rc = AMLITest_Post_GetFieldUnitRegionObj(
  575. &pHData,rc);
  576. }
  577. EXIT(1, ("AMLIGetFieldUnitRegionObj=%x (pns=%x)\n", rc, *ppns));
  578. return rc;
  579. } //AMLIGetFieldUnitRegionObj
  580. /***EP AMLIEvalNameSpaceObject - Evaluate a name space object
  581. *
  582. * @DOC EXTERNAL
  583. *
  584. * @FUNC NTSTATUS | AMLIEvalNameSpaceObject | Evaluate a name space object.
  585. *
  586. * This function evaluate a given object. If the given object is a
  587. * control method, it will execute it. If the given object is a data
  588. * object, the data value is returned in a given buffer.
  589. *
  590. * @PARM PNSOBJ | pns | Pointer to the object to be evaluated.
  591. *
  592. * @PARM POBJDATA | pdataResult | Pointer to the OBJDATA structure which will
  593. * hold the result of the evaluation (can be NULL if don't care about
  594. * result).
  595. *
  596. * @PARM int | icArgs | Specify the number of arguments pass to the method
  597. * object for evaluation (only valid if pns points to a method object).
  598. *
  599. * @PARM POBJDATA | pdataArgs | Pointer to an array of argument data object
  600. * (only valid if pns points to a method object).
  601. *
  602. * @RDESC SUCCESS - Returns STATUS_SUCCESS.
  603. *
  604. * @RDESC FAILURE - Returns NT status code.
  605. *
  606. * @DEVNOTE The returned object may contain buffer pointer to the actual
  607. * data in the ACPI name space. Therefore, the caller must be very
  608. * careful not to overwrite any data in the buffer. Also, the caller
  609. * is responsible for calling AMLIFreeDataBuffs on the result object
  610. * after the result object data is no longer needed.
  611. */
  612. NTSTATUS AMLIAPI AMLIEvalNameSpaceObject(PNSOBJ pns, POBJDATA pdataResult,
  613. int icArgs, POBJDATA pdataArgs)
  614. {
  615. TRACENAME("AMLIEVALNAMESPACEOBJECT")
  616. NTSTATUS rc = STATUS_SUCCESS;
  617. PAMLIHOOK_DATA pHData = NULL;
  618. ENTER(1, ("AMLIEvalNameSpaceObject(Obj=%s,pdataResult=%x,icArgs=%d,pdataArgs=%x)\n",
  619. GetObjectPath(pns), pdataResult, icArgs, pdataArgs));
  620. ASSERT(pns != NULL);
  621. ASSERT((icArgs == 0) || (pdataArgs != NULL));
  622. RESETERR();
  623. CHKGLOBALHEAP();
  624. CHKDEBUGGERREQ();
  625. if(IsAmliHookEnabled())
  626. {
  627. rc = AMLITest_Pre_EvalNameSpaceObject(
  628. pns,pdataResult,icArgs,pdataArgs,&pHData);
  629. if(rc != STATUS_SUCCESS)
  630. return(rc);
  631. }
  632. if (pns->ObjData.dwfData & DATAF_NSOBJ_DEFUNC)
  633. {
  634. AMLI_WARN(("AMLIEvalNameSpaceObject: pnsObj is no longer valid"));
  635. rc = STATUS_NO_SUCH_DEVICE;
  636. }
  637. else
  638. {
  639. if (pdataResult != NULL)
  640. MEMZERO(pdataResult, sizeof(OBJDATA));
  641. pns = GetBaseObject(pns);
  642. #ifdef DEBUGGER
  643. if (gDebugger.dwfDebugger & DBGF_VERBOSE_ON)
  644. {
  645. PRINTF(MODNAME ": %p: EvalNameSpaceObject(%s)\n",
  646. KeGetCurrentThread(), GetObjectPath(pns));
  647. }
  648. #endif
  649. rc = SyncEvalObject(pns, pdataResult, icArgs, pdataArgs);
  650. if (rc == AMLISTA_PENDING)
  651. rc = STATUS_PENDING;
  652. else if (rc != STATUS_SUCCESS)
  653. rc = NTERR(rc);
  654. }
  655. if(IsAmliHookEnabled())
  656. {
  657. rc = AMLITest_Post_EvalNameSpaceObject(
  658. &pHData,rc);
  659. }
  660. EXIT(1, ("AMLIEvalNameSpaceObject=%x\n", rc));
  661. return rc;
  662. } //AMLIEvalNameSpaceObject
  663. /***EP AMLIAsyncEvalObject - Evaluate an object asynchronously
  664. *
  665. * @DOC EXTERNAL
  666. *
  667. * @FUNC NTSTATUS | AMLIAsyncEvalObject | Evaluate an object asynchronously.
  668. *
  669. * @PARM PNSOBJ | pns | Pointer to the object to be evaluated.
  670. *
  671. * @PARM POBJDATA | pdataResult | Pointer to the OBJDATA structure which will
  672. * hold the result of the evaluation (can be NULL if don't care about
  673. * result).
  674. *
  675. * @PARM int | icArgs | Specify the number of arguments pass to the method
  676. * object for evaluation (only valid if pns points to a method object).
  677. *
  678. * @PARM POBJDATA | pdataArgs | Pointer to an array of argument data object
  679. * (only valid if pns points to a method object).
  680. *
  681. * @PARM PFNACB | pfnAsyncCallBack | Pointer to the asynchronous callback
  682. * function in case the control method is blocked and has to be
  683. * completed asynchronously (can be NULL if no Callback required).
  684. *
  685. * @PARM PVOID | pvContext | Pointer to some context data that the
  686. * interpreter will pass to the Async callback handler.
  687. *
  688. * @RDESC SUCCESS - Returns STATUS_SUCCESS.
  689. *
  690. * @RDESC FAILURE - Returns NT status code.
  691. *
  692. * @DEVNOTE The returned object may contain buffer pointer to the actual
  693. * data in the ACPI name space. Therefore, the caller must be very
  694. * careful not to overwrite any data in the buffer. Also, the caller
  695. * is responsible for calling AMLIFreeDataBuffs on the result object
  696. * after the result object data is no longer needed.
  697. */
  698. NTSTATUS AMLIAPI AMLIAsyncEvalObject(PNSOBJ pns, POBJDATA pdataResult,
  699. int icArgs, POBJDATA pdataArgs,
  700. PFNACB pfnAsyncCallBack, PVOID pvContext)
  701. {
  702. TRACENAME("AMLIASYNCEVALOBJECT")
  703. NTSTATUS rc = STATUS_SUCCESS;
  704. PAMLIHOOK_DATA pHData = NULL;
  705. ENTER(1, ("AMLIAsyncEvalObject(Obj=%s,pdataResult=%x,icArgs=%d,pdataArgs=%x,pfnAysnc=%x)\n",
  706. GetObjectPath(pns), pdataResult, icArgs, pdataArgs,
  707. pfnAsyncCallBack));
  708. ASSERT(pns != NULL);
  709. ASSERT((icArgs == 0) || (pdataArgs != NULL));
  710. RESETERR();
  711. CHKGLOBALHEAP();
  712. CHKDEBUGGERREQ();
  713. if(IsAmliHookEnabled())
  714. {
  715. rc = AMLITest_Pre_AsyncEvalObject(
  716. pns,pdataResult,icArgs,pdataArgs,
  717. &pfnAsyncCallBack,&pvContext,&pHData);
  718. if(rc != STATUS_SUCCESS)
  719. return(rc);
  720. }
  721. if (pns->ObjData.dwfData & DATAF_NSOBJ_DEFUNC)
  722. {
  723. AMLI_WARN(("AMLIAsyncEvalObject: pnsObj is no longer valid"));
  724. rc = STATUS_NO_SUCH_DEVICE;
  725. }
  726. else
  727. {
  728. if (pdataResult != NULL)
  729. MEMZERO(pdataResult, sizeof(OBJDATA));
  730. pns = GetBaseObject(pns);
  731. #ifdef DEBUGGER
  732. if (gDebugger.dwfDebugger & DBGF_VERBOSE_ON)
  733. {
  734. PRINTF(MODNAME ": %p: AsyncEvalObject(%s)\n",
  735. KeGetCurrentThread(), GetObjectPath(pns));
  736. }
  737. #endif
  738. rc = AsyncEvalObject(pns, pdataResult, icArgs, pdataArgs,
  739. pfnAsyncCallBack, pvContext, TRUE);
  740. if (rc == AMLISTA_PENDING)
  741. rc = STATUS_PENDING;
  742. else if (rc != STATUS_SUCCESS)
  743. rc = NTERR(rc);
  744. }
  745. if(IsAmliHookEnabled())
  746. {
  747. rc = AMLITest_Post_AsyncEvalObject(
  748. &pHData,rc);
  749. }
  750. EXIT(1, ("AMLIAsyncEvalObject=%x\n", rc));
  751. return rc;
  752. } //AMLIAsyncEvalObject
  753. /***EP AMLINestAsyncEvalObject - Evaluate an object asynchronously from within
  754. * the current context
  755. *
  756. * @DOC EXTERNAL
  757. *
  758. * @FUNC NTSTATUS | AMLINestAsyncEvalObject | Evaluate an object
  759. * asynchronously from within the current context.
  760. *
  761. * @PARM PNSOBJ | pns | Pointer to the object to be evaluated.
  762. *
  763. * @PARM POBJDATA | pdataResult | Pointer to the OBJDATA structure which will
  764. * hold the result of the evaluation (can be NULL if don't care about
  765. * result).
  766. *
  767. * @PARM int | icArgs | Specify the number of arguments pass to the method
  768. * object for evaluation (only valid if pns points to a method object).
  769. *
  770. * @PARM POBJDATA | pdataArgs | Pointer to an array of argument data object
  771. * (only valid if pns points to a method object).
  772. *
  773. * @PARM PFNACB | pfnAsyncCallBack | Pointer to the asynchronous callback
  774. * function in case the control method is blocked and has to be
  775. * completed asynchronously (can be NULL if no Callback required).
  776. *
  777. * @PARM PVOID | pvContext | Pointer to some context data that the
  778. * interpreter will pass to the Async callback handler.
  779. *
  780. * @RDESC SUCCESS - Returns STATUS_SUCCESS.
  781. *
  782. * @RDESC FAILURE - Returns NT status code.
  783. *
  784. * @DEVNOTE The returned object may contain buffer pointer to the actual
  785. * data in the ACPI name space. Therefore, the caller must be very
  786. * careful not to overwrite any data in the buffer. Also, the caller
  787. * is responsible for calling AMLIFreeDataBuffs on the result object
  788. * after the result object data is no longer needed.
  789. */
  790. NTSTATUS AMLIAPI AMLINestAsyncEvalObject(PNSOBJ pns, POBJDATA pdataResult,
  791. int icArgs, POBJDATA pdataArgs,
  792. PFNACB pfnAsyncCallBack,
  793. PVOID pvContext)
  794. {
  795. TRACENAME("AMLINESTASYNCEVALOBJECT")
  796. NTSTATUS rc = STATUS_SUCCESS;
  797. PAMLIHOOK_DATA pHData = NULL;
  798. ENTER(1, ("AMLINestAsyncEvalObject(Obj=%s,pdataResult=%x,icArgs=%d,pdataArgs=%x,pfnAysnc=%x)\n",
  799. GetObjectPath(pns), pdataResult, icArgs, pdataArgs,
  800. pfnAsyncCallBack));
  801. ASSERT(pns != NULL);
  802. ASSERT((icArgs == 0) || (pdataArgs != NULL));
  803. RESETERR();
  804. CHKGLOBALHEAP();
  805. CHKDEBUGGERREQ();
  806. if(IsAmliHookEnabled())
  807. {
  808. rc = AMLITest_Pre_NestAsyncEvalObject(
  809. pns,pdataResult,icArgs,pdataArgs,
  810. &pfnAsyncCallBack,&pvContext,&pHData);
  811. if(rc != STATUS_SUCCESS)
  812. return(rc);
  813. }
  814. if (pns->ObjData.dwfData & DATAF_NSOBJ_DEFUNC)
  815. {
  816. AMLI_WARN(("AMLINestAsyncEvalObject: pnsObj is no longer valid"));
  817. rc = STATUS_NO_SUCH_DEVICE;
  818. }
  819. else
  820. {
  821. if (pdataResult != NULL)
  822. MEMZERO(pdataResult, sizeof(OBJDATA));
  823. pns = GetBaseObject(pns);
  824. #ifdef DEBUGGER
  825. if (gDebugger.dwfDebugger & DBGF_VERBOSE_ON)
  826. {
  827. PRINTF(MODNAME ": %p: AsyncNestEvalObject(%s)\n",
  828. KeGetCurrentThread(), GetObjectPath(pns));
  829. }
  830. #endif
  831. rc = NestAsyncEvalObject(pns, pdataResult, icArgs, pdataArgs,
  832. pfnAsyncCallBack, pvContext, TRUE);
  833. if (rc == AMLISTA_PENDING)
  834. rc = STATUS_PENDING;
  835. else if (rc != STATUS_SUCCESS)
  836. rc = NTERR(rc);
  837. }
  838. if(IsAmliHookEnabled())
  839. {
  840. rc = AMLITest_Post_NestAsyncEvalObject(
  841. &pHData,rc);
  842. }
  843. EXIT(1, ("AMLINestAsyncEvalObject=%x\n", rc));
  844. return rc;
  845. } //AMLINestAsyncEvalObject
  846. /***EP AMLIEvalPackageElement - Evaluate a package element
  847. *
  848. * @DOC EXTERNAL
  849. *
  850. * @FUNC NTSTATUS | AMLIEvalPackageElement | Evaluate a package element.
  851. *
  852. * This function evaluate an element of a given package object.
  853. * A package is essentially an array of objects. This API provides
  854. * a way to evaluate individual element object inside a package.
  855. *
  856. * @PARM PNSOBJ | pns | Pointer to the package object to be evaluated. If
  857. * the object is a method, then the method is evaluated first before
  858. * the resulting package object is evaluated. It is an error if the
  859. * resulting object is not of package type.
  860. *
  861. * @PARM int | iPkgIndex | Package index (0-based).
  862. *
  863. * @PARM POBJDATA | pdataResult | Pointer to the OBJDATA structure which will
  864. * hold the result of the evaluation (can be NULL if don't care about
  865. * result).
  866. *
  867. * @RDESC SUCCESS - Returns STATUS_SUCCESS.
  868. *
  869. * @RDESC FAILURE - Returns NT status code.
  870. *
  871. * @DEVNOTE The returned object may contain buffer pointer to the actual
  872. * data in the ACPI name space. Therefore, the caller must be very
  873. * careful not to overwrite any data in the buffer. Also, the caller
  874. * is responsible for calling AMLIFreeDataBuffs on the result object
  875. * after the result object data is no longer needed.
  876. */
  877. NTSTATUS AMLIAPI AMLIEvalPackageElement(PNSOBJ pns, int iPkgIndex,
  878. POBJDATA pdataResult)
  879. {
  880. TRACENAME("AMLIEVALPACKAGEELEMENT")
  881. NTSTATUS rc = STATUS_SUCCESS;
  882. OBJDATA data;
  883. POBJDATA pdata = NULL;
  884. PAMLIHOOK_DATA pHData = NULL;
  885. ENTER(1, ("AMLIEvalPackageElement(Obj=%s,Index=%d,pdataResult=%x)\n",
  886. GetObjectPath(pns), iPkgIndex, pdataResult));
  887. ASSERT(pns != NULL);
  888. ASSERT(pdataResult != NULL);
  889. RESETERR();
  890. CHKGLOBALHEAP();
  891. CHKDEBUGGERREQ();
  892. if(IsAmliHookEnabled())
  893. {
  894. rc = AMLITest_Pre_EvalPackageElement(
  895. pns,iPkgIndex,pdataResult,&pHData);
  896. if(rc != STATUS_SUCCESS)
  897. return(rc);
  898. }
  899. if (pns->ObjData.dwfData & DATAF_NSOBJ_DEFUNC)
  900. {
  901. AMLI_WARN(("AMLIEvalPackageElement: pnsObj is no longer valid"));
  902. rc = STATUS_NO_SUCH_DEVICE;
  903. }
  904. else
  905. {
  906. MEMZERO(pdataResult, sizeof(OBJDATA));
  907. MEMZERO(&data, sizeof(data));
  908. pns = GetBaseObject(pns);
  909. #ifdef DEBUGGER
  910. if (gDebugger.dwfDebugger & DBGF_VERBOSE_ON)
  911. {
  912. PRINTF(MODNAME ": %p: EvalPackageElement(%s,%d)\n",
  913. KeGetCurrentThread(), GetObjectPath(pns), iPkgIndex);
  914. }
  915. #endif
  916. if (pns->ObjData.dwDataType == OBJTYPE_METHOD)
  917. {
  918. if ((rc = SyncEvalObject(pns, &data, 0, NULL)) == STATUS_SUCCESS)
  919. {
  920. if (data.dwDataType == OBJTYPE_PKGDATA)
  921. pdata = &data;
  922. else
  923. {
  924. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE,
  925. ("AMLIEvalPackageElement: result object of the method is not package (ObjType=%s)",
  926. GetObjectTypeName(data.dwDataType)));
  927. }
  928. }
  929. }
  930. else if (pns->ObjData.dwDataType == OBJTYPE_PKGDATA)
  931. {
  932. pdata = &pns->ObjData;
  933. }
  934. else
  935. {
  936. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE,
  937. ("AMLIEvalPackageElement: object is not a method or package (ObjType=%s)",
  938. GetObjectTypeName(pns->ObjData.dwDataType)));
  939. }
  940. if (rc == STATUS_SUCCESS)
  941. {
  942. rc = EvalPackageElement((PPACKAGEOBJ)pdata->pbDataBuff, iPkgIndex,
  943. pdataResult);
  944. }
  945. FreeDataBuffs(&data, 1);
  946. if (rc == AMLISTA_PENDING)
  947. rc = STATUS_PENDING;
  948. else if (rc != STATUS_SUCCESS)
  949. rc = NTERR(rc);
  950. else
  951. {
  952. ASSERT((pdataResult->pbDataBuff == NULL) ||
  953. !(pdataResult->dwfData & DATAF_BUFF_ALIAS));
  954. }
  955. }
  956. if(IsAmliHookEnabled())
  957. {
  958. rc = AMLITest_Post_EvalPackageElement(
  959. &pHData,rc);
  960. }
  961. EXIT(1, ("AMLIEvalPackageElement=%x\n", rc));
  962. return rc;
  963. } //AMLIEvalPackageElement
  964. /***EP AMLIEvalPkgDataElement - Evaluate an element of a package data
  965. *
  966. * @DOC EXTERNAL
  967. *
  968. * @FUNC NTSTATUS | AMLIEvalPkgDataElement | Evaluate a package data element.
  969. *
  970. * This function evaluate an element of a given package data object.
  971. * A package is essentially an array of objects. This API provides
  972. * a way to evaluate individual element object inside a package.
  973. *
  974. * @PARM POBJDATA | pdataPkg | Pointer to the package data object to be
  975. * evaluated. It is an error if the data object is not of package
  976. * type.
  977. *
  978. * @PARM int | iPkgIndex | Package index (0-based).
  979. *
  980. * @PARM POBJDATA | pdataResult | Pointer to the OBJDATA structure which will
  981. * hold the result of the evaluation (can be NULL if don't care about
  982. * result).
  983. *
  984. * @RDESC SUCCESS - Returns STATUS_SUCCESS.
  985. *
  986. * @RDESC FAILURE - Returns NT status code.
  987. *
  988. * @DEVNOTE The returned object may contain buffer pointer to the actual
  989. * data in the ACPI name space. Therefore, the caller must be very
  990. * careful not to overwrite any data in the buffer. Also, the caller
  991. * is responsible for calling AMLIFreeDataBuffs on the result object
  992. * after the result object data is no longer needed.
  993. */
  994. NTSTATUS AMLIAPI AMLIEvalPkgDataElement(POBJDATA pdataPkg, int iPkgIndex,
  995. POBJDATA pdataResult)
  996. {
  997. TRACENAME("AMLIEVALPKGDATAELEMENT")
  998. NTSTATUS rc = STATUS_SUCCESS;
  999. PAMLIHOOK_DATA pHData = NULL;
  1000. ENTER(1, ("AMLIEvalPkgDataElement(pdataPkg=%x,Index=%d,pdataResult=%x)\n",
  1001. pdataPkg, iPkgIndex, pdataResult));
  1002. ASSERT(pdataResult != NULL);
  1003. RESETERR();
  1004. CHKGLOBALHEAP();
  1005. CHKDEBUGGERREQ();
  1006. MEMZERO(pdataResult, sizeof(OBJDATA));
  1007. if(IsAmliHookEnabled())
  1008. {
  1009. rc = AMLITest_Pre_EvalPkgDataElement(
  1010. pdataPkg,iPkgIndex,pdataResult,&pHData);
  1011. if(rc != STATUS_SUCCESS)
  1012. return(rc);
  1013. }
  1014. #ifdef DEBUGGER
  1015. if (gDebugger.dwfDebugger & DBGF_VERBOSE_ON)
  1016. {
  1017. PRINTF(MODNAME ": %p: EvalPkgDataElement(%x,%d)\n",
  1018. KeGetCurrentThread(), pdataPkg, iPkgIndex);
  1019. }
  1020. #endif
  1021. if (pdataPkg->dwDataType != OBJTYPE_PKGDATA)
  1022. {
  1023. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE,
  1024. ("AMLIEvalPkgDataElement: object is not a package (ObjType=%s)",
  1025. GetObjectTypeName(pdataPkg->dwDataType)));
  1026. }
  1027. else
  1028. {
  1029. rc = EvalPackageElement((PPACKAGEOBJ)pdataPkg->pbDataBuff, iPkgIndex,
  1030. pdataResult);
  1031. }
  1032. if (rc == AMLISTA_PENDING)
  1033. rc = STATUS_PENDING;
  1034. else if (rc != STATUS_SUCCESS)
  1035. rc = NTERR(rc);
  1036. else
  1037. {
  1038. ASSERT((pdataResult->pbDataBuff == NULL) ||
  1039. !(pdataResult->dwfData & DATAF_BUFF_ALIAS));
  1040. }
  1041. if(IsAmliHookEnabled())
  1042. {
  1043. rc = AMLITest_Post_EvalPkgDataElement(
  1044. &pHData,rc);
  1045. }
  1046. EXIT(1, ("AMLIEvalPkgDataElement=%x\n", rc));
  1047. return rc;
  1048. } //AMLIEvalPkgDataElement
  1049. /***EP AMLIFreeDataBuffs - Free data buffers of an object array
  1050. *
  1051. * @DOC EXTERNAL
  1052. *
  1053. * @FUNC VOID | AMLIFreeDataBuffs | Free data buffers of a data object
  1054. * array.
  1055. *
  1056. * This function is typically called after evaluating an object to
  1057. * free the result object buffers.
  1058. *
  1059. * @PARM POBJDATA | pdata | Pointer to the object array.
  1060. *
  1061. * @PARM int | icData | Specifies the number of objects in the array.
  1062. *
  1063. * @RDESC None.
  1064. */
  1065. VOID AMLIAPI AMLIFreeDataBuffs(POBJDATA pdata, int icData)
  1066. {
  1067. TRACENAME("AMLIFREEDATABUFFS")
  1068. PAMLIHOOK_DATA pHData = NULL;
  1069. ENTER(1, ("AMLIFreeDataBuffs(pdata=%x,icData=%d)\n", pdata, icData));
  1070. ASSERT(pdata != NULL);
  1071. ASSERT(icData > 0);
  1072. RESETERR();
  1073. if(IsAmliHookEnabled())
  1074. {
  1075. AMLITest_Pre_FreeDataBuffs(
  1076. pdata,icData,&pHData);
  1077. }
  1078. FreeDataBuffs(pdata, icData);
  1079. if(IsAmliHookEnabled())
  1080. {
  1081. AMLITest_Post_FreeDataBuffs(
  1082. &pHData,STATUS_SUCCESS);
  1083. }
  1084. EXIT(1, ("AMLIFreeDataBuffs!\n"));
  1085. } //AMLIFreeDataBuffs
  1086. /***EP AMLIRegEventHandler - Register an event handler
  1087. *
  1088. * @DOC EXTERNAL
  1089. *
  1090. * @FUNC NTSTATUS | AMLIRegEventHandler | Register an event handler.
  1091. * handler.
  1092. *
  1093. * This function allows the caller to hook a callback handler for some
  1094. * AMLI events.
  1095. *
  1096. * @PARM ULONG | dwEventType | Event type the handler will handle.
  1097. *
  1098. * @PARM ULONG_PTR | uipEventData | Event specific data the handler will
  1099. * handle.
  1100. *
  1101. * @PARM PFNHND | pfnHandler | Callback handler entry point (can be NULL
  1102. * if deregistering previous handler).
  1103. *
  1104. * @PARM ULONG_PTR | uipParam | Parameter Data (will be passed to the
  1105. * callback handler).
  1106. *
  1107. * @RDESC None.
  1108. */
  1109. NTSTATUS AMLIAPI AMLIRegEventHandler(ULONG dwEventType, ULONG_PTR uipEventData,
  1110. PFNHND pfnHandler, ULONG_PTR uipParam)
  1111. {
  1112. TRACENAME("AMLIREGEVENTHANDLER")
  1113. NTSTATUS rc = STATUS_SUCCESS;
  1114. PAMLIHOOK_DATA pHData = NULL;
  1115. ENTER(1, ("AMLIRegEventHandler(EventType=%x,EventData=%x,pfnHandler=%x,Param=%x)\n",
  1116. dwEventType, uipEventData, pfnHandler, uipParam));
  1117. RESETERR();
  1118. if(IsAmliHookEnabled())
  1119. {
  1120. rc = AMLIHook_Pre_RegEventHandler(
  1121. dwEventType,uipEventData,&pfnHandler,&uipParam,&pHData);
  1122. if(rc != STATUS_SUCCESS)
  1123. return(rc);
  1124. }
  1125. switch (dwEventType)
  1126. {
  1127. case EVTYPE_OPCODE:
  1128. rc = RegOpcodeHandler((ULONG)uipEventData, (PFNOH)pfnHandler,
  1129. uipParam, 0);
  1130. break;
  1131. case EVTYPE_OPCODE_EX:
  1132. rc = RegOpcodeHandler((ULONG)uipEventData, (PFNOH)pfnHandler,
  1133. uipParam, OF_CALLBACK_EX);
  1134. break;
  1135. case EVTYPE_NOTIFY:
  1136. rc = RegEventHandler(&ghNotify, pfnHandler, uipParam);
  1137. break;
  1138. case EVTYPE_FATAL:
  1139. rc = RegEventHandler(&ghFatal, pfnHandler, uipParam);
  1140. break;
  1141. case EVTYPE_VALIDATE_TABLE:
  1142. rc = RegEventHandler(&ghValidateTable, pfnHandler, uipParam);
  1143. break;
  1144. case EVTYPE_ACQREL_GLOBALLOCK:
  1145. rc = RegEventHandler(&ghGlobalLock, pfnHandler, uipParam);
  1146. break;
  1147. case EVTYPE_RS_COOKACCESS:
  1148. rc = RegRSAccess((ULONG)uipEventData, pfnHandler, uipParam, FALSE);
  1149. break;
  1150. case EVTYPE_RS_RAWACCESS:
  1151. rc = RegRSAccess((ULONG)uipEventData, pfnHandler, uipParam, TRUE);
  1152. break;
  1153. case EVTYPE_CREATE:
  1154. rc = RegEventHandler(&ghCreate, pfnHandler, uipParam);
  1155. break;
  1156. case EVTYPE_DESTROYOBJ:
  1157. rc =RegEventHandler(&ghDestroyObj, pfnHandler, uipParam);
  1158. break;
  1159. #ifdef DEBUGGER
  1160. case EVTYPE_CON_MESSAGE:
  1161. rc = RegEventHandler(&gDebugger.hConMessage, pfnHandler, uipParam);
  1162. break;
  1163. case EVTYPE_CON_PROMPT:
  1164. rc = RegEventHandler(&gDebugger.hConPrompt, pfnHandler, uipParam);
  1165. break;
  1166. #endif
  1167. default:
  1168. rc = AMLI_LOGERR(AMLIERR_INVALID_EVENTTYPE,
  1169. ("AMLIRegEventHandler: invalid event type %x",
  1170. dwEventType));
  1171. }
  1172. if (rc == AMLISTA_PENDING)
  1173. rc = STATUS_PENDING;
  1174. else if (rc != STATUS_SUCCESS)
  1175. rc = NTERR(rc);
  1176. if(IsAmliHookEnabled())
  1177. {
  1178. rc = AMLIHook_Post_RegEventHandler(
  1179. &pHData,rc);
  1180. }
  1181. EXIT(1, ("AMLIRegEventHandler=%x\n", rc));
  1182. return rc;
  1183. } //AMLIRegEventHandler
  1184. /***EP AMLIPauseInterpreter
  1185. *
  1186. * @DOC EXTERNAL
  1187. *
  1188. * @FUNC NTSTATUS | AMLIPauseInterpreter | Flush the interpreter queue
  1189. * and pause the interpreter so that all subsequent new method
  1190. * execution requests will be queued.
  1191. *
  1192. * @RDESC SUCCESS - Returns STATUS_SUCCESS.
  1193. *
  1194. * @RDESC FAILURE - Returns NT status code.
  1195. */
  1196. NTSTATUS AMLIAPI AMLIPauseInterpreter(PFNAA pfnCallback, PVOID Context)
  1197. {
  1198. TRACENAME("AMLIPAUSEINTERPRETER")
  1199. NTSTATUS rc = STATUS_SUCCESS;
  1200. PAMLIHOOK_DATA pHData = NULL;
  1201. ENTER(1, ("AMLIPauseInterpreter(Callback=%p,Context=%p)\n",
  1202. pfnCallback, Context));
  1203. RESETERR();
  1204. if(IsAmliHookEnabled())
  1205. {
  1206. rc = AMLITest_Pre_PauseInterpreter(
  1207. &pfnCallback,&Context,&pHData);
  1208. if(rc != STATUS_SUCCESS)
  1209. return(rc);
  1210. }
  1211. AcquireMutex(&gReadyQueue.mutCtxtQ);
  1212. if (!(gReadyQueue.dwfCtxtQ & (CQF_PAUSED | CQF_FLUSHING)))
  1213. {
  1214. if (gplistCtxtHead == NULL)
  1215. {
  1216. //
  1217. // There is no pending ctxt.
  1218. //
  1219. gReadyQueue.dwfCtxtQ |= CQF_PAUSED;
  1220. }
  1221. else
  1222. {
  1223. //
  1224. // There are pending ctxts, so we go into flushing mode.
  1225. //
  1226. gReadyQueue.dwfCtxtQ |= CQF_FLUSHING;
  1227. gReadyQueue.pfnPauseCallback = pfnCallback;
  1228. gReadyQueue.PauseCBContext = Context;
  1229. rc = AMLISTA_PENDING;
  1230. }
  1231. }
  1232. else
  1233. {
  1234. rc = AMLI_LOGERR(AMLIERR_FATAL,
  1235. ("AMLIPauseInterpreter: interpreter already entered paused state"));
  1236. }
  1237. ReleaseMutex(&gReadyQueue.mutCtxtQ);
  1238. LOGSCHEDEVENT('PAUS', (ULONG_PTR)rc, 0, 0);
  1239. if (rc == AMLISTA_PENDING)
  1240. rc = STATUS_PENDING;
  1241. else if (rc != STATUS_SUCCESS)
  1242. rc = NTERR(rc);
  1243. if(IsAmliHookEnabled())
  1244. {
  1245. rc = AMLITest_Post_PauseInterpreter(
  1246. &pHData,rc);
  1247. }
  1248. EXIT(1, ("AMLIPauseInterpreter=%x\n", rc));
  1249. return rc;
  1250. } //AMLIPauseInterpreter
  1251. /***EP AMLIResumeInterpreter
  1252. *
  1253. * @DOC EXTERNAL
  1254. *
  1255. * @FUNC VOID | AMLIResumeInterpreter | Resume the interpreter from
  1256. * paused state.
  1257. *
  1258. * @RDESC None.
  1259. */
  1260. VOID AMLIAPI AMLIResumeInterpreter(VOID)
  1261. {
  1262. PAMLIHOOK_DATA pHData = NULL;
  1263. TRACENAME("AMLIRESUMEINTERPRETER")
  1264. ENTER(1, ("AMLIResumeInterpreter()\n"));
  1265. RESETERR();
  1266. if(IsAmliHookEnabled())
  1267. {
  1268. AMLITest_Pre_ResumeInterpreter(
  1269. &pHData);
  1270. }
  1271. AcquireMutex(&gReadyQueue.mutCtxtQ);
  1272. if (gReadyQueue.dwfCtxtQ & (CQF_PAUSED | CQF_FLUSHING))
  1273. {
  1274. gReadyQueue.dwfCtxtQ &= ~(CQF_PAUSED | CQF_FLUSHING);
  1275. gReadyQueue.pfnPauseCallback = NULL;
  1276. gReadyQueue.PauseCBContext = NULL;
  1277. LOGSCHEDEVENT('RSUM', 0, 0, 0);
  1278. if ((gReadyQueue.plistCtxtQ != NULL) &&
  1279. !(gReadyQueue.dwfCtxtQ & CQF_WORKITEM_SCHEDULED))
  1280. {
  1281. OSQueueWorkItem(&gReadyQueue.WorkItem);
  1282. gReadyQueue.dwfCtxtQ |= CQF_WORKITEM_SCHEDULED;
  1283. LOGSCHEDEVENT('RSTQ', 0, 0, 0);
  1284. }
  1285. }
  1286. else
  1287. {
  1288. AMLI_WARN(("AMLIResumeInterpreter: not in paused state"));
  1289. }
  1290. ReleaseMutex(&gReadyQueue.mutCtxtQ);
  1291. if(IsAmliHookEnabled())
  1292. {
  1293. AMLITest_Post_ResumeInterpreter(
  1294. &pHData,STATUS_SUCCESS);
  1295. }
  1296. EXIT(1, ("AMLIResumeInterpreter!\n"));
  1297. } //AMLIResumeInterpreter
  1298. /***EP AMLIReferenceObject - Bump up the reference count of the object
  1299. *
  1300. * @DOC EXTERNAL
  1301. *
  1302. * @FUNC VOID | AMLIReferenceObject | Bump up the reference count of the
  1303. * name space object.
  1304. *
  1305. * @PARM PNSOBJ | pnsObj | Points to the name space object.
  1306. *
  1307. * @RDESC None.
  1308. */
  1309. VOID AMLIAPI AMLIReferenceObject(PNSOBJ pnsObj)
  1310. {
  1311. TRACENAME("AMLIREFERENCEOBJECT")
  1312. ENTER(1, ("AMLIReferenceObject(pnsObj=%x)\n", pnsObj));
  1313. RESETERR();
  1314. ASSERT(pnsObj != NULL);
  1315. pnsObj->dwRefCount++;
  1316. EXIT(1, ("AMLIReferenceObj!\n"));
  1317. } //AMLIReferenceObject
  1318. /***EP AMLIDereferenceObject - Bump down the reference count of the object
  1319. *
  1320. * @DOC EXTERNAL
  1321. *
  1322. * @FUNC VOID | AMLIDereferenceObject | Bump down the reference count of the
  1323. * name space object. If it reaches zero and it is in defunc state,
  1324. * deallocate the object.
  1325. *
  1326. * @PARM PNSOBJ | pnsObj | Points to the name space object.
  1327. *
  1328. * @RDESC None.
  1329. */
  1330. VOID AMLIAPI AMLIDereferenceObject(PNSOBJ pnsObj)
  1331. {
  1332. TRACENAME("AMLIDEREFERENCEOBJECT")
  1333. ENTER(1, ("AMLIDereferenceObject(pnsObj=%x)\n", pnsObj));
  1334. RESETERR();
  1335. ASSERT(pnsObj != NULL);
  1336. ASSERT(pnsObj->dwRefCount > 0);
  1337. if (pnsObj->dwRefCount > 0)
  1338. {
  1339. pnsObj->dwRefCount--;
  1340. if ((pnsObj->dwRefCount == 0) && (pnsObj->ObjData.dwfData & DATAF_NSOBJ_DEFUNC))
  1341. {
  1342. ListRemoveEntry(&pnsObj->list, &gplistDefuncNSObjs);
  1343. FREENSOBJ(pnsObj);
  1344. }
  1345. }
  1346. EXIT(1, ("AMLIDereferenceObj!\n"));
  1347. } //AMLIDereferenceObject
  1348. /***EP AMLIDestroyFreedObjs - Destroy freed objects during an unload
  1349. *
  1350. * @DOC EXTERNAL
  1351. *
  1352. * @FUNC NTSTATUS | AMLIDestroyFreedObjs | Destroy freed objects from a
  1353. * previous unload.
  1354. *
  1355. * @PARM PNSOBJ | pnsObj | The object in the freed list to be destroyed.
  1356. *
  1357. * @RDESC SUCCESS - Returns STATUS_SUCCESS.
  1358. *
  1359. * @RDESC FAILURE - Returns NT status code.
  1360. */
  1361. NTSTATUS AMLIAPI AMLIDestroyFreedObjs(PNSOBJ pnsObj)
  1362. {
  1363. TRACENAME("AMLIDESTROYFREEDOBJS")
  1364. ENTER(1, ("AMLIDestroyFreedObjs(pnsObj=%x)\n",pnsObj));
  1365. RESETERR();
  1366. ASSERT(pnsObj != NULL);
  1367. //
  1368. // Destroy the namespace object
  1369. //
  1370. FreeNameSpaceObjects(pnsObj);
  1371. EXIT(1, ("AMLIDestroyFreedObjs=%x \n",STATUS_SUCCESS));
  1372. return STATUS_SUCCESS;
  1373. } //AMLIDestroyFreedObjs
  1374. #ifdef DEBUGGER
  1375. /***EP AMLIGetLastError - Get last error code and message
  1376. *
  1377. * @DOC EXTERNAL
  1378. *
  1379. * @FUNC NTSTATUS | AMLIGetLastError | Get last error code and associated
  1380. * error message.
  1381. *
  1382. * @PARM PSZ * | ppszErrMsg | Point to a variable to hold the error message
  1383. * buffer pointer. If there is no error, the variable is set to NULL.
  1384. *
  1385. * @RDESC Returns the last error code.
  1386. */
  1387. NTSTATUS AMLIAPI AMLIGetLastError(PSZ *ppszErrMsg)
  1388. {
  1389. TRACENAME("AMLIGETLASTERROR")
  1390. NTSTATUS rc = STATUS_SUCCESS;
  1391. ENTER(1, ("AMLIGetLastError(ppszErrMsg=%x)\n", ppszErrMsg));
  1392. ASSERT(ppszErrMsg != NULL);
  1393. if ((rc = gDebugger.rcLastError) != STATUS_SUCCESS)
  1394. *ppszErrMsg = gDebugger.szLastError;
  1395. else
  1396. *ppszErrMsg = NULL;
  1397. EXIT(1, ("AMLIGetLastError=%x (Msg=%s)\n",
  1398. rc, *ppszErrMsg? *ppszErrMsg: "<null>"));
  1399. return rc;
  1400. } //AMLIGetLastError
  1401. #endif //ifdef DEBUGGER