/*** parser.c - AML Parser * * Copyright (c) 1996,1997 Microsoft Corporation * Author: Michael Tsang (MikeTs) * Created 06/13/97 * * MODIFICATION HISTORY */ #include "pch.h" #ifdef LOCKABLE_PRAGMA #pragma ACPI_LOCKABLE_DATA #pragma ACPI_LOCKABLE_CODE #endif /***LP ParseScope - Parse a scope * * ENTRY * pctxt -> CTXT * pscope -> SCOPE * rc - status code * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseScope(PCTXT pctxt, PSCOPE pscope, NTSTATUS rc) { TRACENAME("PARSESCOPE") ULONG dwStage = ((rc == STATUS_SUCCESS) || (rc == AMLISTA_BREAK))? (pscope->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 2; ENTER(2, ("ParseScope(Stage=%d,pctxt=%p,pbOp=%p,pscope=%p,rc=%x)\n", dwStage, pctxt, pctxt->pbOp, pscope, rc)); ASSERT(pscope->FrameHdr.dwSig == SIG_SCOPE); switch (dwStage) { case 0: // // Stage 0: Do debug print if necessary. // #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PrintIndent(pctxt); PRINTF("{"); gDebugger.iPrintLevel++; pscope->FrameHdr.dwfFrame |= SCOPEF_FIRST_TERM; } #endif // // There is nothing blockable, so continue to next stage. // pscope->FrameHdr.dwfFrame++; case 1: Stage1: // // Stage 1: Parse next opcode. // if (rc == AMLISTA_BREAK) { pctxt->pbOp = pscope->pbOpEnd; rc = STATUS_SUCCESS; } else { while (pctxt->pbOp < pscope->pbOpEnd) { #ifdef DEBUGGER gDebugger.pbUnAsm = pctxt->pbOp; if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { if (pscope->FrameHdr.dwfFrame & SCOPEF_FIRST_TERM) { pscope->FrameHdr.dwfFrame &= ~SCOPEF_FIRST_TERM; } else if (gDebugger.dwfDebugger & DBGF_STEP_OVER) { gDebugger.dwfDebugger &= ~DBGF_STEP_OVER; AMLIDebugger(FALSE); } } if ((gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) && (*pctxt->pbOp != OP_PACKAGE)) { PrintIndent(pctxt); } #endif // // Discard result of previous term if any. // FreeDataBuffs(pscope->pdataResult, 1); if (((rc = ParseOpcode(pctxt, pscope->pbOpEnd, pscope->pdataResult)) != STATUS_SUCCESS) || (&pscope->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd)) { break; } } if (rc == AMLISTA_BREAK) { pctxt->pbOp = pscope->pbOpEnd; rc = STATUS_SUCCESS; } else if ((rc == AMLISTA_PENDING) || (&pscope->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd)) { break; } else if ((rc == STATUS_SUCCESS) && (pctxt->pbOp < pscope->pbOpEnd)) { goto Stage1; } } // // If we come here, there was no more opcode in this scope, so // continue to next stage. // pscope->FrameHdr.dwfFrame++; case 2: // // Stage 2: clean up. // #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { gDebugger.iPrintLevel--; PrintIndent(pctxt); PRINTF("}"); } #endif pctxt->pnsScope = pscope->pnsPrevScope; pctxt->powner = pscope->pownerPrev; pctxt->pheapCurrent = pscope->pheapPrev; if (pscope->pbOpRet != NULL) { pctxt->pbOp = pscope->pbOpRet; } PopFrame(pctxt); } EXIT(2, ("ParseScope=%x\n", rc)); return rc; } //ParseScope /***LP ParseNestedContext - Parse and evaluate a nested context * * ENTRY * pctxt -> CTXT * pcall -> CALL * rc - status code * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseNestedContext(PCTXT pctxt, PNESTEDCTXT pnctxt, NTSTATUS rc) { TRACENAME("PARSENESTEDCONTEXT") ENTER(2, ("ParseNestedContext(pctxt=%x,pnctxt=%x,rc=%x)\n", pctxt, pnctxt, rc)); ASSERT(pctxt->dwfCtxt & CTXTF_NEST_EVAL); if ((rc == STATUS_SUCCESS) && (pnctxt->pdataCallBack != NULL)) { rc = DupObjData(gpheapGlobal, pnctxt->pdataCallBack, &pnctxt->Result); } AsyncCallBack(pctxt, rc); FreeDataBuffs(&pnctxt->Result, 1); pctxt->dwfCtxt &= ~CTXTF_ASYNC_EVAL; pctxt->dwfCtxt |= pnctxt->dwfPrevCtxt & CTXTF_ASYNC_EVAL; pctxt->pnctxt = pnctxt->pnctxtPrev; PopFrame(pctxt); EXIT(2, ("ParseNestedContext=%x (rcEval=%x)\n", AMLISTA_DONE, rc)); return AMLISTA_DONE; } //ParseNestedContext /***LP ParseCall - Parse and evaluate a method call * * ENTRY * pctxt -> CTXT * pcall -> CALL * rc - status code * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseCall(PCTXT pctxt, PCALL pcall, NTSTATUS rc) { TRACENAME("PARSECALL") ULONG dwStage = (rc == STATUS_SUCCESS)? (pcall->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 4; PMETHODOBJ pm; POBJOWNER powner; ENTER(2, ("ParseCall(Stage=%d,pctxt=%x,pbOp=%x,pcall=%x,rc=%x)\n", dwStage, pctxt, pctxt->pbOp, pcall, rc)); ASSERT(pcall->FrameHdr.dwSig == SIG_CALL); pm = (pcall->pnsMethod != NULL)? (PMETHODOBJ)pcall->pnsMethod->ObjData.pbDataBuff: NULL; switch (dwStage) { case 0: // // Stage 0: Print debug stuff if necessary. // pcall->FrameHdr.dwfFrame++; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("("); } #endif case 1: Stage1: // // Stage 1: Parse arguments. // while (pcall->iArg < pcall->icArgs) { // // There are still arguments, parse it. // #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { if (pcall->iArg > 0) { PRINTF(","); } } #endif rc = ParseArg(pctxt, 'C', &pcall->pdataArgs[pcall->iArg++]); if ((rc != STATUS_SUCCESS) || (&pcall->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd)) { break; } } if ((rc != STATUS_SUCCESS) || (&pcall->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd)) { break; } else if (pcall->iArg < pcall->icArgs) { goto Stage1; } // // If we come here, there is no more argument, so we can fall // through to the next stage. // #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF(")"); } #endif pcall->FrameHdr.dwfFrame++; case 2: // // Stage 2: Acquire mutex if necessary // pcall->FrameHdr.dwfFrame++; if(pm) { if (pm->bMethodFlags & METHOD_SERIALIZED) { PACQUIRE pacq; if ((rc = PushFrame(pctxt, SIG_ACQUIRE, sizeof(ACQUIRE), ParseAcquire, &pacq)) == STATUS_SUCCESS) { pacq->pmutex = &pm->Mutex; pacq->wTimeout = 0xffff; pacq->pdataResult = pcall->pdataResult; } break; } } else { rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED, ("ParseCall: pcall->pnsMethod == NULL")); break; } case 3: // // Stage 3: Invoke the method. // pcall->FrameHdr.dwfFrame++; // // If we come here, we must have acquired the serialization mutex. // if (pcall->FrameHdr.dwfFrame & CALLF_NEED_MUTEX) { pcall->FrameHdr.dwfFrame |= CALLF_ACQ_MUTEX; } if ((rc = NewObjOwner(pctxt->pheapCurrent, &powner)) == STATUS_SUCCESS) { pcall->pownerPrev = pctxt->powner; pctxt->powner = powner; pcall->pcallPrev = pctxt->pcall; pctxt->pcall = pcall; pcall->FrameHdr.dwfFrame |= CALLF_INVOKE_CALL; rc = PushScope(pctxt, pm->abCodeBuff, pcall->pnsMethod->ObjData.pbDataBuff + pcall->pnsMethod->ObjData.dwDataLen, pctxt->pbOp, pcall->pnsMethod, powner, pctxt->pheapCurrent, pcall->pdataResult); break; } case 4: // // Stage 4: Clean up. // pcall->FrameHdr.dwfFrame++; if (rc == AMLISTA_RETURN) { rc = STATUS_SUCCESS; } if (pcall->pdataResult->dwfData & DATAF_BUFF_ALIAS) { OBJDATA data; // // The result object is an alias. It could be an alias of // ArgX or LocalX. We better dup it because we are going // to blow ArgX and LocalX away. // DupObjData(pctxt->pheapCurrent, &data, pcall->pdataResult); FreeDataBuffs(pcall->pdataResult, 1); MoveObjData(pcall->pdataResult, &data); } FreeDataBuffs(pcall->Locals, MAX_NUM_LOCALS); if (pcall->FrameHdr.dwfFrame & CALLF_INVOKE_CALL) { FreeObjOwner(pctxt->powner, FALSE); pctxt->powner = pcall->pownerPrev; pctxt->pcall = pcall->pcallPrev; } else if (pcall->pnsMethod == NULL) { // // This is the dummy call frame for LoadDDB. All NameSpace // objects created by LoadDDB are persistent (i.e. don't // destroy them). // pctxt->powner = pcall->pownerPrev; pctxt->pcall = pcall->pcallPrev; } if (pcall->pdataArgs != NULL) { FreeDataBuffs(pcall->pdataArgs, pcall->icArgs); FREEODOBJ(pcall->pdataArgs); } if (pcall->FrameHdr.dwfFrame & CALLF_ACQ_MUTEX) { ReleaseASLMutex(pctxt, &pm->Mutex); } case 5: // // Stage 5: This stage is for the dummy call frame to exit. // PopFrame(pctxt); } EXIT(2, ("ParseCall=%x\n", rc)); return rc; } //ParseCall /***LP ParseTerm - Parse and evaluate an ASL term * * ENTRY * pctxt -> CTXT * pterm -> TERM * rc - status code * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseTerm(PCTXT pctxt, PTERM pterm, NTSTATUS rc) { TRACENAME("PARSETERM") ULONG dwStage = (rc == STATUS_SUCCESS)? (pterm->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 4; int i; ENTER(2, ("ParseTerm(Term=%s,Stage=%d,pctxt=%x,pbOp=%x,pterm=%x,rc=%x)\n", pterm->pamlterm->pszTermName, dwStage, pctxt, pctxt->pbOp, pterm, rc)); ASSERT(pterm->FrameHdr.dwSig == SIG_TERM); switch (dwStage) { case 0: // // Stage 0: Parse package length if any. // pterm->FrameHdr.dwfFrame++; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { if (pterm->pamlterm->dwOpcode == OP_PACKAGE) { gDebugger.iPrintLevel++; PrintIndent(pctxt); } PRINTF("%s", pterm->pamlterm->pszTermName); if (pterm->icArgs > 0) { PRINTF("("); } } #endif if (pterm->pamlterm->dwfOpcode & OF_VARIABLE_LIST) { ParsePackageLen(&pctxt->pbOp, &pterm->pbOpEnd); } case 1: Stage1: // // Stage 1: Parse arguments. // while (pterm->iArg < pterm->icArgs) { i = pterm->iArg++; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { if (i > 0) { PRINTF(","); } } #endif rc = ParseArg(pctxt, pterm->pamlterm->pszArgTypes[i], &pterm->pdataArgs[i]); if ((rc != STATUS_SUCCESS) || (&pterm->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd)) { break; } } if ((rc != STATUS_SUCCESS) || (&pterm->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd)) { break; } else if (pterm->iArg < pterm->icArgs) { goto Stage1; } // // If we come here, there is no more argument, so we can fall // through to the next stage. // pterm->FrameHdr.dwfFrame++; case 2: // // Stage 2: Execute the term and prepare to go to the next stage. // pterm->FrameHdr.dwfFrame++; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { if (pterm->icArgs > 0) { PRINTF(")"); } } #endif if ((pterm->pamlterm->dwfOpcode & OF_CALLBACK_EX) && (pterm->pamlterm->pfnCallBack != NULL)) { ((PFNOPEX)pterm->pamlterm->pfnCallBack)( EVTYPE_OPCODE_EX, OPEXF_NOTIFY_PRE, pterm->pamlterm->dwOpcode, pterm->pnsObj, pterm->pamlterm->dwCBData); } if (pterm->pamlterm->pfnOpcode != NULL) { if (((rc = pterm->pamlterm->pfnOpcode(pctxt, pterm)) != STATUS_SUCCESS) || (&pterm->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd)) { break; } } case 3: // // Stage 3: Do Opcode Callback if any // pterm->FrameHdr.dwfFrame++; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { if ((pterm->pamlterm->dwOpcode != OP_BUFFER) && (pterm->pamlterm->dwOpcode != OP_PACKAGE)) { if (pterm->pamlterm->dwTermClass == TC_OPCODE_TYPE2) { PRINTF("="); PrintObject(pterm->pdataResult); } } } if (gDebugger.dwfDebugger & DBGF_SINGLE_STEP) { gDebugger.dwfDebugger &= ~DBGF_SINGLE_STEP; AMLIDebugger(FALSE); } else { #endif if (pterm->pamlterm->pfnCallBack != NULL) { if (pterm->pamlterm->dwfOpcode & OF_CALLBACK_EX) { ((PFNOPEX)pterm->pamlterm->pfnCallBack)( EVTYPE_OPCODE_EX, OPEXF_NOTIFY_POST, pterm->pamlterm->dwOpcode, pterm->pnsObj, pterm->pamlterm->dwCBData); } else { pterm->pamlterm->pfnCallBack( EVTYPE_OPCODE, pterm->pamlterm->dwOpcode, pterm->pnsObj, pterm->pamlterm->dwCBData ); } } #ifdef DEBUGGER } #endif case 4: // // Stage 4: Clean up. // #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { if (pterm->pamlterm->dwOpcode == OP_PACKAGE) { gDebugger.iPrintLevel--; } } #endif if (pterm->pdataArgs != NULL) { FreeDataBuffs(pterm->pdataArgs, pterm->icArgs); FREEODOBJ(pterm->pdataArgs); } PopFrame(pctxt); } EXIT(2, ("ParseTerm=%x\n", rc)); return rc; } //ParseTerm /***LP ParseAcquire - Parse and evaluate an Acquire term * * ENTRY * pctxt -> CTXT * pacq - ACQUIRE * rc - status code * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseAcquire(PCTXT pctxt, PACQUIRE pacq, NTSTATUS rc) { TRACENAME("PARSEACQUIRE") ULONG dwStage = (rc == STATUS_SUCCESS)? (pacq->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 2; ENTER(2, ("ParseAcquire(Stage=%d,pctxt=%x,pbOp=%x,pacq=%x,rc=%x)\n", dwStage, pctxt, pctxt->pbOp, pacq, rc)); ASSERT(pacq->FrameHdr.dwSig == SIG_ACQUIRE); switch (dwStage) { case 0: // // Stage 0: Acquire GlobalLock if necessary. // pacq->FrameHdr.dwfFrame++; if (pacq->FrameHdr.dwfFrame & ACQF_NEED_GLOBALLOCK) { if ((rc = AcquireGL(pctxt)) != STATUS_SUCCESS) { break; } } case 1: // // Stage 1: Acquire the mutex. // if (pacq->FrameHdr.dwfFrame & ACQF_NEED_GLOBALLOCK) { // // If we come here, we must have acquired the global lock. // pacq->FrameHdr.dwfFrame |= ACQF_HAVE_GLOBALLOCK; } rc = AcquireASLMutex(pctxt, pacq->pmutex, pacq->wTimeout); if (rc == AMLISTA_PENDING) { // // If it is pending, we must release the global lock and // retry the whole operation. // if (pacq->FrameHdr.dwfFrame & ACQF_HAVE_GLOBALLOCK) { pacq->FrameHdr.dwfFrame &= ~ACQF_HAVE_GLOBALLOCK; if ((rc = ReleaseGL(pctxt)) == STATUS_SUCCESS) { pacq->FrameHdr.dwfFrame--; } else { pacq->FrameHdr.dwfFrame++; rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED, ("ParseAcquire: failed to release global lock (rc=%x)", rc)); } } break; } else { if (pacq->FrameHdr.dwfFrame & ACQF_SET_RESULT) { pacq->pdataResult->dwDataType = OBJTYPE_INTDATA; if (rc == AMLISTA_TIMEOUT) { pacq->pdataResult->uipDataValue = DATAVALUE_ONES; rc = STATUS_SUCCESS; } else { pacq->pdataResult->uipDataValue = DATAVALUE_ZERO; } } } pacq->FrameHdr.dwfFrame++; case 2: // // Stage 2: Clean up. // PopFrame(pctxt); } EXIT(2, ("ParseAcquire=%x\n", rc)); return rc; } //ParseAcquire /***LP ParseOpcode - Parse AML opcode * * ENTRY * pctxt -> CTXT * pbScopeEnd -> end of current scope * pdataResult -> result object * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseOpcode(PCTXT pctxt, PUCHAR pbScopeEnd, POBJDATA pdataResult) { TRACENAME("PARSEOPCODE") NTSTATUS rc = STATUS_SUCCESS; PUCHAR pbOpTerm; PAMLTERM pamlterm; #ifdef DEBUGGER int iBrkPt; #endif ENTER(2, ("ParseOpcode(pctxt=%x,pbOp=%x,pbScopeEnd=%x,pdataResult=%x)\n", pctxt, pctxt->pbOp, pbScopeEnd, pdataResult)); ASSERT(pdataResult != NULL); #ifdef DEBUGGER if ((iBrkPt = CheckBP(pctxt->pbOp)) != -1) { PRINTF("\nHit Breakpoint %d.\n", iBrkPt); AMLIDebugger(FALSE); } #endif pbOpTerm = pctxt->pbOp; if (*pctxt->pbOp == OP_EXT_PREFIX) { pctxt->pbOp++; pamlterm = FindOpcodeTerm(*pctxt->pbOp, ExOpcodeTable); } else { pamlterm = OpcodeTable[*pctxt->pbOp]; } if (pamlterm == NULL) { rc = AMLI_LOGERR(AMLIERR_INVALID_OPCODE, ("ParseOpcode: invalid opcode 0x%02x at 0x%08x", *pctxt->pbOp, pctxt->pbOp)); } else if (pamlterm->dwfOpcode & OF_DATA_OBJECT) { rc = ParseIntObj(&pctxt->pbOp, pdataResult, FALSE); } else if (pamlterm->dwfOpcode & OF_STRING_OBJECT) { rc = ParseString(&pctxt->pbOp, pdataResult, FALSE); } else if (pamlterm->dwfOpcode & OF_ARG_OBJECT) { rc = ParseArgObj(pctxt, pdataResult); } else if (pamlterm->dwfOpcode & OF_LOCAL_OBJECT) { rc = ParseLocalObj(pctxt, pdataResult); } else if (pamlterm->dwfOpcode & OF_NAME_OBJECT) { rc = ParseNameObj(pctxt, pdataResult); } else if (pamlterm->dwfOpcode & OF_DEBUG_OBJECT) { rc = AMLI_LOGERR(AMLIERR_FATAL, ("ParseOpcode: debug object cannot be evaluated")); } else { // // Must be an ASL Term. // pctxt->pbOp++; rc = PushTerm(pctxt, pbOpTerm, pbScopeEnd, pamlterm, pdataResult); } EXIT(2, ("ParseOpcode=%x (pbOp=%x,pamlterm=%x)\n", rc, pctxt->pbOp, pamlterm)); return rc; } //ParseOpcode /***LP ParseArgObj - Parse and execute the ArgX instruction * * ENTRY * pctxt -> CTXT * pdataResult -> result object * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseArgObj(PCTXT pctxt, POBJDATA pdataResult) { TRACENAME("PARSEARGOBJ") NTSTATUS rc = STATUS_SUCCESS; int i; ENTER(2, ("ParseArgObj(pctxt=%x,pbOp=%x,pdataResult=%x)\n", pctxt, pctxt->pbOp, pdataResult)); ASSERT(pdataResult != NULL); i = *pctxt->pbOp - OP_ARG0; if (i >= pctxt->pcall->icArgs) { rc = AMLI_LOGERR(AMLIERR_ARG_NOT_EXIST, ("ParseArgObj: Arg%d does not exist", i)); } else { CopyObjData(pdataResult, &pctxt->pcall->pdataArgs[i]); pctxt->pbOp++; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("Arg%d=", i); PrintObject(pdataResult); } #endif } EXIT(2, ("ParseArgObj=%x (pbOp=%x)\n", rc, pctxt->pbOp)); return rc; } //ParseArgObj /***LP ParseLocalObj - Parse and execute the LocalX instruction * * ENTRY * pctxt -> CTXT * pdataResult -> Result object * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseLocalObj(PCTXT pctxt, POBJDATA pdataResult) { TRACENAME("PARSELOCALOBJ") NTSTATUS rc = STATUS_SUCCESS; int i; ENTER(2, ("ParseLocalObj(pctxt=%x,pbOp=%x,pdataResult=%x)\n", pctxt, pctxt->pbOp, pdataResult)); ASSERT(pdataResult != NULL); i = *pctxt->pbOp - OP_LOCAL0; CopyObjData(pdataResult, &pctxt->pcall->Locals[i]); #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("Local%d=", i); PrintObject(pdataResult); } #endif pctxt->pbOp++; EXIT(2, ("ParseLocalObj=%x (pbOp=%x)\n", rc, pctxt->pbOp)); return rc; } //ParseLocalObj /***LP ParseNameObj - Parse and evaluate an AML name object * * ENTRY * pctxt -> CTXT * pdataResult -> result object * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseNameObj(PCTXT pctxt, POBJDATA pdataResult) { TRACENAME("PARSENAMEOBJ") NTSTATUS rc = STATUS_SUCCESS; PNSOBJ pns = NULL; ENTER(2, ("ParseNameObj(pctxt=%x,pbOp=%x,pdataResult=%x)\n", pctxt, pctxt->pbOp, pdataResult)); ASSERT(pdataResult != NULL); rc = ParseAndGetNameSpaceObject(&pctxt->pbOp, pctxt->pnsScope, &pns, FALSE); if (rc == STATUS_SUCCESS) { pns = GetBaseObject(pns); if (pns->ObjData.dwDataType == OBJTYPE_METHOD) { rc = PushCall(pctxt, pns, pdataResult); } else { rc = ReadObject(pctxt, &pns->ObjData, pdataResult); } } EXIT(2, ("ParseNameObj=%x\n", rc)); return rc; } //ParseNameObj /***LP ParseAndGetNameSpaceObject - Parse NameSpace path and get the object * * ENTRY * ppbOp -> opcode pointer * pnsScope - current scope * ppns -> to hold the object found * fAbsentOK - if TRUE, do not print error message when object is not * found * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseAndGetNameSpaceObject(PUCHAR *ppbOp, PNSOBJ pnsScope, PPNSOBJ ppns, BOOLEAN fAbsentOK) { TRACENAME("PARSEANDGETNAMESPACEOBJECT") NTSTATUS rc; char szNameBuff[MAX_NAME_LEN + 1]; ENTER(2, ("ParseAndGetNameSpaceObject(pbOp=%x,Scope=%s,ppns=%x,fAbsentOK=%x)\n", *ppbOp, GetObjectPath(pnsScope), ppns, fAbsentOK)); if ((rc = ParseName(ppbOp, szNameBuff, sizeof(szNameBuff))) == STATUS_SUCCESS) { rc = GetNameSpaceObject(szNameBuff, pnsScope, ppns, 0); if (rc == AMLIERR_OBJ_NOT_FOUND) { if (fAbsentOK) { rc = STATUS_SUCCESS; *ppns = NULL; } else { rc = AMLI_LOGERR(rc, ("ParseAndGetNameSpaceObject: object %s not found", szNameBuff)); } } } EXIT(2, ("ParseAndGetNameSpaceObject=%x (Name=%s)\n", rc, szNameBuff)); return rc; } //ParseAndGetNameSpaceObject /***LP ParseArg - Parse and evaluate an argument * * ENTRY * pctxt -> CTXT * chArgType - expected argument type * pdataArg -> argument object * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseArg(PCTXT pctxt, char chArgType, POBJDATA pdataArg) { TRACENAME("PARSEARG") NTSTATUS rc = STATUS_SUCCESS; ENTER(2, ("ParseArg(pctxt=%x,pbOp=%x,ArgType=%c,pdataArg=%x)\n", pctxt, pctxt->pbOp, chArgType, pdataArg)); ASSERT(pdataArg != NULL); switch (chArgType) { case ARGTYPE_NAME: rc = ParseObjName(&pctxt->pbOp, pdataArg, FALSE); break; case ARGTYPE_DATAOBJ: if (((rc = ParseIntObj(&pctxt->pbOp, pdataArg, TRUE)) == AMLIERR_INVALID_OPCODE) && ((rc = ParseString(&pctxt->pbOp, pdataArg, TRUE)) == AMLIERR_INVALID_OPCODE) && ((*pctxt->pbOp == OP_BUFFER) || (*pctxt->pbOp == OP_PACKAGE))) { rc = PushTerm(pctxt, pctxt->pbOp, NULL, OpcodeTable[*pctxt->pbOp], pdataArg); pctxt->pbOp++; } break; case ARGTYPE_BYTE: rc = ParseInteger(&pctxt->pbOp, pdataArg, sizeof(UCHAR)); break; case ARGTYPE_WORD: rc = ParseInteger(&pctxt->pbOp, pdataArg, sizeof(USHORT)); break; case ARGTYPE_DWORD: rc = ParseInteger(&pctxt->pbOp, pdataArg, sizeof(ULONG)); break; case ARGTYPE_SNAME: rc = ParseSuperName(pctxt, pdataArg, FALSE); break; case ARGTYPE_SNAME2: rc = ParseSuperName(pctxt, pdataArg, TRUE); break; case ARGTYPE_OPCODE: rc = ParseOpcode(pctxt, NULL, pdataArg); break; default: rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED, ("ParseArg: unexpected arguemnt type (%c)", chArgType)); } EXIT(2, ("ParseArg=%x\n", rc)); return rc; } //ParseArg /***LP ParseSuperName - Parse AML SuperName * * ENTRY * pctxt -> CTXT * pdata -> object data * fAbsentOK - If TRUE, it is not an error for the object to be absent * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseSuperName(PCTXT pctxt, POBJDATA pdata, BOOLEAN fAbsentOK) { TRACENAME("PARSESUPERNAME") NTSTATUS rc = STATUS_SUCCESS; PAMLTERM pamlterm; PNSOBJ pns = NULL; int i; ENTER(2, ("ParseSuperName(pctxt=%x,pbOp=%x,pdata=%x,fAbsentOK=%x)\n", pctxt, pctxt->pbOp, pdata, fAbsentOK)); ASSERT(pdata != NULL); if (*pctxt->pbOp == 0) { ASSERT(pdata->dwDataType == OBJTYPE_UNKNOWN); pctxt->pbOp++; } else if ((*pctxt->pbOp == OP_EXT_PREFIX) && (*(pctxt->pbOp + 1) == EXOP_DEBUG)) { pctxt->pbOp += 2; pdata->dwDataType = OBJTYPE_DEBUG; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("Debug"); } #endif } else if ((pamlterm = OpcodeTable[*pctxt->pbOp]) == NULL) { rc = AMLI_LOGERR(AMLIERR_INVALID_SUPERNAME, ("ParseSuperName: invalid SuperName - 0x%02x at 0x%08x", *pctxt->pbOp, pctxt->pbOp)); } else if (pamlterm->dwfOpcode & OF_NAME_OBJECT) { rc = ParseAndGetNameSpaceObject(&pctxt->pbOp, pctxt->pnsScope, &pns, fAbsentOK); if (rc == STATUS_SUCCESS) { if (pns != NULL) { pdata->dwDataType = OBJTYPE_OBJALIAS; pdata->pnsAlias = GetBaseObject(pns); } else { ASSERT(pdata->dwDataType == OBJTYPE_UNKNOWN); } } } else if (pamlterm->dwfOpcode & OF_ARG_OBJECT) { i = *pctxt->pbOp - OP_ARG0; pctxt->pbOp++; if (i < pctxt->pcall->icArgs) { #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("Arg%d", i); } #endif pdata->dwDataType = OBJTYPE_DATAALIAS; pdata->pdataAlias = GetBaseData(&pctxt->pcall->pdataArgs[i]); } else { rc = AMLI_LOGERR(AMLIERR_ARG_NOT_EXIST, ("ParseSuperName: Arg%d does not exist", i)); } } else if (pamlterm->dwfOpcode & OF_LOCAL_OBJECT) { i = *pctxt->pbOp - OP_LOCAL0; pctxt->pbOp++; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("Local%d", i); } #endif pdata->dwDataType = OBJTYPE_DATAALIAS; pdata->pdataAlias = &pctxt->pcall->Locals[i]; } else if (pamlterm->dwfOpcode & OF_REF_OBJECT) { rc = PushTerm(pctxt, pctxt->pbOp, NULL, pamlterm, pdata); pctxt->pbOp++; } else { rc = AMLI_LOGERR(AMLIERR_INVALID_SUPERNAME, ("ParseSuperName: invalid SuperName %x at %x", *pctxt->pbOp, pctxt->pbOp)); } EXIT(2, ("ParseSuperName=%x\n", rc)); return rc; } //ParseSuperName /***LP ParseIntObj - Parse AML integer object * * ENTRY * ppbOp -> opcode pointer * pdataResult -> result object * fErrOK - TRUE if error is OK * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseIntObj(PUCHAR *ppbOp, POBJDATA pdataResult, BOOLEAN fErrOK) { TRACENAME("PARSEINTOBJ") NTSTATUS rc = STATUS_SUCCESS; UCHAR bOp; ENTER(2, ("ParseIntObj(pbOp=%x,pdataResult=%x,fErrOK=%x)\n", *ppbOp, pdataResult, fErrOK)); ASSERT(pdataResult != NULL); bOp = **ppbOp; (*ppbOp)++; pdataResult->dwDataType = OBJTYPE_INTDATA; pdataResult->uipDataValue = 0; switch (bOp) { case OP_ZERO: pdataResult->uipDataValue = DATAVALUE_ZERO; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("Zero"); } #endif break; case OP_ONE: pdataResult->uipDataValue = DATAVALUE_ONE; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("One"); } #endif break; case OP_ONES: pdataResult->uipDataValue = DATAVALUE_ONES; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("Ones"); } #endif break; case OP_REVISION: pdataResult->uipDataValue = AMLI_REVISION; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("Revision"); } #endif break; case OP_BYTE: MEMCPY(&pdataResult->uipDataValue, *ppbOp, sizeof(UCHAR)); (*ppbOp) += sizeof(UCHAR); #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("0x%x", pdataResult->uipDataValue); } #endif break; case OP_WORD: MEMCPY(&pdataResult->uipDataValue, *ppbOp, sizeof(USHORT)); (*ppbOp) += sizeof(USHORT); #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("0x%x", pdataResult->uipDataValue); } #endif break; case OP_DWORD: MEMCPY(&pdataResult->uipDataValue, *ppbOp, sizeof(ULONG)); (*ppbOp) += sizeof(ULONG); #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("0x%x", pdataResult->uipDataValue); } #endif break; default: (*ppbOp)--; if (fErrOK) { rc = AMLIERR_INVALID_OPCODE; } else { rc = AMLI_LOGERR(AMLIERR_INVALID_OPCODE, ("ParseIntObj: invalid opcode 0x%02x at 0x%08x", **ppbOp, *ppbOp)); } } EXIT(2, ("ParseIntObj=%x (pbOp=%x,Value=%x)\n", rc, *ppbOp, pdataResult->uipDataValue)); return rc; } //ParseIntObj /***LP ParseString - Parse AML string object * * ENTRY * ppbOp -> opcode pointer * pdataResult -> result object * fErrOK - TRUE if error is OK * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseString(PUCHAR *ppbOp, POBJDATA pdataResult, BOOLEAN fErrOK) { TRACENAME("PARSESTRING") NTSTATUS rc = STATUS_SUCCESS; ENTER(2, ("ParseString(pbOp=%x,pdataResult=%x,fErrOK=%x)\n", *ppbOp, pdataResult, fErrOK)); ASSERT(pdataResult != NULL); if (**ppbOp == OP_STRING) { (*ppbOp)++; pdataResult->dwDataType = OBJTYPE_STRDATA; pdataResult->dwDataLen = STRLEN((PSZ)*ppbOp) + 1; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PRINTF("\"%s\"", *ppbOp); } #endif if ((pdataResult->pbDataBuff = NEWSDOBJ(gpheapGlobal, pdataResult->dwDataLen)) == NULL) { rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM, ("ParseString: failed to allocate string buffer")); } else { MEMCPY(pdataResult->pbDataBuff, *ppbOp, pdataResult->dwDataLen); } (*ppbOp) += pdataResult->dwDataLen; } else if (fErrOK) { rc = AMLIERR_INVALID_OPCODE; } else { rc = AMLI_LOGERR(AMLIERR_INVALID_OPCODE, ("ParseStrObj: invalid opcode 0x%02x at 0x%08x", **ppbOp, *ppbOp)); } EXIT(2, ("ParseString=%x (Value=%s)\n", rc, pdataResult->pbDataBuff? (PSZ)pdataResult->pbDataBuff: "")); return rc; } //ParseString /***LP ParseObjName - Parse AML object name * * ENTRY * ppbOp -> opcode pointer * pdata -> to hold name data * fErrOK - TRUE if error is OK * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseObjName(PUCHAR *ppbOp, POBJDATA pdata, BOOLEAN fErrOK) { TRACENAME("PARSEOBJNAME") NTSTATUS rc = STATUS_SUCCESS; PAMLTERM pamlterm = OpcodeTable[**ppbOp]; char szNameBuff[MAX_NAME_LEN+1]; ENTER(2, ("ParseObjName(pbOp=%x,pdata=%x,fErrOK=%x)\n", *ppbOp, pdata, fErrOK)); ASSERT(pdata != NULL); if ((pamlterm == NULL) || !(pamlterm->dwfOpcode & OF_NAME_OBJECT)) { if (fErrOK) { rc = AMLIERR_INVALID_OPCODE; } else { rc = AMLI_LOGERR(AMLIERR_INVALID_OPCODE, ("ParseObjName: invalid opcode 0x%02x at 0x%08x", **ppbOp, *ppbOp)); } } else if ((rc = ParseName(ppbOp, szNameBuff, sizeof(szNameBuff))) == STATUS_SUCCESS) { pdata->dwDataType = OBJTYPE_STRDATA; pdata->dwDataLen = STRLEN(szNameBuff) + 1; if ((pdata->pbDataBuff = (PUCHAR)NEWSDOBJ(gpheapGlobal, pdata->dwDataLen)) == NULL) { rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM, ("ParseObjName: failed to allocate name buffer - %s", szNameBuff)); } else { MEMCPY(pdata->pbDataBuff, szNameBuff, pdata->dwDataLen); } } EXIT(2, ("ParseObjName=%x (Name=%s)\n", rc, szNameBuff)); return rc; } //ParseObjName /***LP ParseName - Parse AML name * * ENTRY * ppbOp -> opcode pointer * pszBuff -> to hold parsed name * dwLen - buffer length * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseName(PUCHAR *ppbOp, PSZ pszBuff, ULONG dwLen) { TRACENAME("PARSENAME") NTSTATUS rc = STATUS_SUCCESS; ENTER(2, ("ParseName(pbOp=%x,pszBuff=%x,Len=%d)\n", *ppbOp, pszBuff, dwLen)); if (**ppbOp == OP_ROOT_PREFIX) { if (dwLen > 1) { STRCPY(pszBuff, "\\"); (*ppbOp)++; rc = ParseNameTail(ppbOp, pszBuff, dwLen); } else { rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG, ("ParseName: name too long - \"%s\"", pszBuff)); } } else if (**ppbOp == OP_PARENT_PREFIX) { if (dwLen > 1) { int i; STRCPY(pszBuff, "^"); for ((*ppbOp)++, i = 1; (i < (int)dwLen) && (**ppbOp == OP_PARENT_PREFIX); (*ppbOp)++, i++) { pszBuff[i] = '^'; } pszBuff[i] = '\0'; if (**ppbOp == OP_PARENT_PREFIX) { rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG, ("ParseName: name too long - \"%s\"", pszBuff)); } else { rc = ParseNameTail(ppbOp, pszBuff, dwLen); } } else { rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG, ("ParseName: name too long - \"%s\"", pszBuff)); } } else if (dwLen > 0) { pszBuff[0] = '\0'; rc = ParseNameTail(ppbOp, pszBuff, dwLen); } else { rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG, ("ParseName: name too long - \"%s\"", pszBuff)); } #ifdef DEBUGGER if ((rc == STATUS_SUCCESS) && (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))) { PRINTF("%s", pszBuff); } #endif EXIT(2, ("ParseName=%x (Name=%s)\n", rc, pszBuff)); return rc; } //ParseName /***LP ParseNameTail - Parse AML name tail * * ENTRY * ppbOp -> opcode pointer * pszBuff -> to hold parsed name * dwLen - buffer length * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseNameTail(PUCHAR *ppbOp, PSZ pszBuff, ULONG dwLen) { TRACENAME("PARSENAMETAIL") NTSTATUS rc = STATUS_SUCCESS; int iLen; int icNameSegs = 0; ENTER(2, ("ParseNameTail(pbOp=%x,Name=%s,Len=%d)\n", *ppbOp, pszBuff, dwLen)); // // We do not check for invalid NameSeg characters here and assume that // the compiler does its job not generating it. // iLen = STRLEN(pszBuff); if (**ppbOp == '\0') { // // There is no NameTail (i.e. either NULL name or name with just // prefixes. // (*ppbOp)++; } else if (**ppbOp == OP_MULTI_NAME_PREFIX) { (*ppbOp)++; icNameSegs = (int)**ppbOp; (*ppbOp)++; } else if (**ppbOp == OP_DUAL_NAME_PREFIX) { (*ppbOp)++; icNameSegs = 2; } else icNameSegs = 1; while ((icNameSegs > 0) && (iLen + sizeof(NAMESEG) < dwLen)) { STRCPYN(&pszBuff[iLen], (PSZ)(*ppbOp), sizeof(NAMESEG)); iLen += sizeof(NAMESEG); (*ppbOp) += sizeof(NAMESEG); icNameSegs--; if ((icNameSegs > 0) && (iLen + 1 < (int)dwLen)) { STRCPY(&pszBuff[iLen], "."); iLen++; } } if (icNameSegs > 0) { rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG, ("ParseNameTail: name too long - %s", pszBuff)); } EXIT(2, ("ParseNameTail=%x (Name=%s)\n", rc, pszBuff)); return rc; } //ParseNameTail /***LP ParseInteger - Parse AML integer object * * ENTRY * ppbOp -> opcode pointer * pdata -> to hold data * dwDataLen - data length in bytes * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseInteger(PUCHAR *ppbOp, POBJDATA pdata, ULONG dwDataLen) { TRACENAME("PARSEINTEGER") NTSTATUS rc = STATUS_SUCCESS; ENTER(2, ("ParseInteger(pbOp=%x,pdata=%x,DataLen=%d)\n", *ppbOp, pdata, dwDataLen)); ASSERT(pdata != NULL); pdata->dwDataType = OBJTYPE_INTDATA; pdata->uipDataValue = 0; MEMCPY(&pdata->uipDataValue, *ppbOp, dwDataLen); (*ppbOp) += dwDataLen; #ifdef DEBUGGER if ((rc == STATUS_SUCCESS) && (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))) { PRINTF("0x%x", pdata->uipDataValue); } #endif EXIT(2, ("ParseInteger=%x (Value=%x,pbOp=%x)\n", rc, pdata->uipDataValue, *ppbOp)); return rc; } //ParseInteger /***LP ParseField - Parse AML field data * * ENTRY * pctxt -> CTXT * pnsParent -> parent * pdwFieldFlags -> field flags * pdwBitPos -> to hold the bit position parsed * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseField(PCTXT pctxt, PNSOBJ pnsParent, PULONG pdwFieldFlags, PULONG pdwBitPos) { TRACENAME("PARSEFIELD") NTSTATUS rc = STATUS_SUCCESS; char szName[sizeof(NAMESEG) + 1]; ENTER(2, ("ParseField(pctxt=%x,pbOp=%x,pnsParent=%x,FieldFlags=%x,BitPos=%x)\n", pctxt, pctxt->pbOp, pnsParent, *pdwFieldFlags, *pdwBitPos)); if (*pctxt->pbOp == 0x01) { pctxt->pbOp++; *pdwFieldFlags &= ~ACCTYPE_MASK; *pdwFieldFlags |= *pctxt->pbOp & ACCTYPE_MASK; pctxt->pbOp++; *pdwFieldFlags &= ~ACCATTRIB_MASK; *pdwFieldFlags |= (ULONG)*pctxt->pbOp << 8; pctxt->pbOp++; #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PrintIndent(pctxt); PRINTF("AccessAs(0x%x,0x%x)", *pdwFieldFlags & 0xff, (*pdwFieldFlags >> 8) & 0xff); } #endif } else { ULONG dwcbBits, dwAccSize = ACCSIZE(*pdwFieldFlags); PNSOBJ pns; if (*pctxt->pbOp == 0) { szName[0] = '\0'; pctxt->pbOp++; } else { STRCPYN(szName, (PSZ)pctxt->pbOp, sizeof(NAMESEG)); pctxt->pbOp += sizeof(NAMESEG); } dwcbBits = ParsePackageLen(&pctxt->pbOp, NULL); #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PrintIndent(pctxt); if (szName[0] == '\0') { if ((dwcbBits > 32) && (((*pdwBitPos + dwcbBits) % 8) == 0)) { PRINTF("Offset(0x%x)", (*pdwBitPos + dwcbBits)/8); } else { PRINTF(",%d", dwcbBits); } } else { PRINTF("%s,%d", szName, dwcbBits); } } #endif if ((rc = CreateNameSpaceObject(pctxt->pheapCurrent, szName, pctxt->pnsScope, pctxt->powner, &pns, 0)) == STATUS_SUCCESS) { pns->ObjData.dwDataType = OBJTYPE_FIELDUNIT; pns->ObjData.dwDataLen = sizeof(FIELDUNITOBJ); if ((pns->ObjData.pbDataBuff = NEWFUOBJ(pctxt->pheapCurrent, pns->ObjData.dwDataLen)) == NULL) { rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM, ("ParseField: failed to allocate FieldUnit object")); } else { PFIELDUNITOBJ pfu; MEMZERO(pns->ObjData.pbDataBuff, pns->ObjData.dwDataLen); pfu = (PFIELDUNITOBJ)pns->ObjData.pbDataBuff; pfu->pnsFieldParent = pnsParent; pfu->FieldDesc.dwFieldFlags = *pdwFieldFlags; pfu->FieldDesc.dwByteOffset = (*pdwBitPos / (dwAccSize*8))* dwAccSize; pfu->FieldDesc.dwStartBitPos = *pdwBitPos - pfu->FieldDesc.dwByteOffset*8; pfu->FieldDesc.dwNumBits = dwcbBits; (*pdwBitPos) += dwcbBits; } } } EXIT(2, ("ParseField=%x (Field=%s,BitPos=%x)\n", rc, szName, *pdwBitPos)); return rc; } //ParseField /***LP ParseFieldList - Parse the FieldUnit list * * ENTRY * pctxt -> CTXT * pbOpEnd -> end of field list * pnsParent -> parent * dwFieldFlags - field flags * dwRegionLen - length of operation region (0xffffffff if no length limit) * * EXIT-SUCCESS * returns STATUS_SUCCESS * EXIT-FAILURE * returns AMLIERR_ code */ NTSTATUS LOCAL ParseFieldList(PCTXT pctxt, PUCHAR pbOpEnd, PNSOBJ pnsParent, ULONG dwFieldFlags, ULONG dwRegionLen) { TRACENAME("PARSESFIELDLIST") NTSTATUS rc = STATUS_SUCCESS; ULONG dwBitPos = 0; ENTER(2, ("ParseFieldList(pctxt=%x,pbOp=%x,pnsParent=%x,FieldFlags=%x,RegionLen=%x)\n", pctxt, pctxt->pbOp, pnsParent, dwFieldFlags, dwRegionLen)); #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { PrintIndent(pctxt); PRINTF("{"); gDebugger.iPrintLevel++; } #endif while ((rc == STATUS_SUCCESS) && (pctxt->pbOp < pbOpEnd)) { if ((rc = ParseField(pctxt, pnsParent, &dwFieldFlags, &dwBitPos)) == STATUS_SUCCESS) { #ifdef DEBUGGER if ((gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) && (rc == STATUS_SUCCESS) && (pctxt->pbOp < pbOpEnd)) { PRINTF(","); } #endif if ((dwRegionLen != 0xffffffff) && ((dwBitPos + 7)/8 > dwRegionLen)) { rc = AMLI_LOGERR(AMLIERR_INDEX_TOO_BIG, ("ParseFieldList: offset exceeds OpRegion range (Offset=0x%x, RegionLen=0x%x)", (dwBitPos + 7)/8, dwRegionLen)); } } } #ifdef DEBUGGER if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) { gDebugger.iPrintLevel--; PrintIndent(pctxt); PRINTF("}"); } #endif EXIT(2, ("ParseFieldList=%x\n", rc)); return rc; } //ParseFieldList /***LP ParsePackageLen - parse package length * * ENTRY * ppbOp -> instruction pointer * ppbOpNext -> to hold pointer to next instruction (can be NULL) * * EXIT * returns package length */ ULONG LOCAL ParsePackageLen(PUCHAR *ppbOp, PUCHAR *ppbOpNext) { TRACENAME("PARSEPACKAGELEN") ULONG dwLen; UCHAR bFollowCnt, i; ENTER(2, ("ParsePackageLen(pbOp=%x,ppbOpNext=%x)\n", *ppbOp, ppbOpNext)); if (ppbOpNext != NULL) *ppbOpNext = *ppbOp; dwLen = (ULONG)(**ppbOp); (*ppbOp)++; bFollowCnt = (UCHAR)((dwLen & 0xc0) >> 6); if (bFollowCnt != 0) { dwLen &= 0x0000000f; for (i = 0; i < bFollowCnt; ++i) { dwLen |= (ULONG)(**ppbOp) << (i*8 + 4); (*ppbOp)++; } } if (ppbOpNext != NULL) *ppbOpNext += dwLen; EXIT(2, ("ParsePackageLen=%x (pbOp=%x,pbOpNext=%x)\n", dwLen, *ppbOp, ppbOpNext? *ppbOpNext: 0)); return dwLen; } //ParsePackageLen