windows-nt/Source/XPSP1/NT/base/busdrv/acpi/tools/kdext/kdutil.c
2020-09-26 16:20:57 +08:00

397 lines
9.4 KiB
C

/*** kdutil.c - KD Extension Utility Functions
*
* This module contains KD Extension Utility Functions.
*
* Copyright (c) 1999 Microsoft Corporation
* Author: Michael Tsang (MikeTs)
* Created 06/22/99
*
* MODIFICATION HISTORY
*/
#include "pch.h"
/***EP MemZero - Fill target buffer with zeros
*
* ENTRY
* uipAddr - target buffer address
* dwSize - target buffer size
*
* EXIT
* None
*/
VOID MemZero(ULONG_PTR uipAddr, ULONG dwSize)
{
PUCHAR pbBuff;
//
// LPTR will zero init the buffer
//
if ((pbBuff = LocalAlloc(LPTR, dwSize)) != NULL)
{
if (!WriteMemory(uipAddr, pbBuff, dwSize, NULL))
{
DBG_ERROR(("MemZero: failed to write memory"));
}
LocalFree(pbBuff);
}
else
{
DBG_ERROR(("MemZero: failed to allocate buffer"));
}
} //MemZero
/***EP ReadMemByte - Read a byte from target address
*
* ENTRY
* uipAddr - target address
*
* EXIT
* None
*/
BYTE ReadMemByte(ULONG_PTR uipAddr)
{
BYTE bData = 0;
if (!ReadMemory(uipAddr, &bData, sizeof(bData), NULL))
{
DBG_ERROR(("ReadMemByte: failed to read address %x", uipAddr));
}
return bData;
} //ReadMemByte
/***EP ReadMemWord - Read a word from target address
*
* ENTRY
* uipAddr - target address
*
* EXIT
* None
*/
WORD ReadMemWord(ULONG_PTR uipAddr)
{
WORD wData = 0;
if (!ReadMemory(uipAddr, &wData, sizeof(wData), NULL))
{
DBG_ERROR(("ReadMemWord: failed to read address %x", uipAddr));
}
return wData;
} //ReadMemWord
/***EP ReadMemDWord - Read a dword from target address
*
* ENTRY
* uipAddr - target address
*
* EXIT
* None
*/
DWORD ReadMemDWord(ULONG_PTR uipAddr)
{
DWORD dwData = 0;
if (!ReadMemory(uipAddr, &dwData, sizeof(dwData), NULL))
{
DBG_ERROR(("ReadMemDWord: failed to read address %x", uipAddr));
}
return dwData;
} //ReadMemDWord
/***EP ReadMemUlongPtr - Read a ulong ptr from target address
*
* ENTRY
* uipAddr - target address
*
* EXIT
* None
*/
ULONG_PTR ReadMemUlongPtr(ULONG_PTR uipAddr)
{
ULONG_PTR uipData = 0;
if (!ReadMemory(uipAddr, &uipData, sizeof(uipData), NULL))
{
DBG_ERROR(("ReadMemUlongPtr: failed to read address %x", uipAddr));
}
return uipData;
} //ReadMemUlongPtr
/***LP GetObjBuff - Allocate and read object buffer
*
* ENTRY
* pdata -> object data
*
* EXIT
* return the allocated object buffer pointer
*/
PVOID LOCAL GetObjBuff(POBJDATA pdata)
{
PVOID pbuff;
if ((pbuff = LocalAlloc(LPTR, pdata->dwDataLen)) == NULL)
{
DBG_ERROR(("failed to allocate object buffer (size=%d)",
pdata->dwDataLen));
}
else if (!ReadMemory((ULONG_PTR)pdata->pbDataBuff,
pbuff,
pdata->dwDataLen,
NULL))
{
DBG_ERROR(("failed to read object buffer at %x", pdata->pbDataBuff));
LocalFree(pbuff);
pbuff = NULL;
}
return pbuff;
} //GetObjBuff
/***LP GetNSObj - Find a name space object
*
* ENTRY
* pszObjPath -> object path string
* pnsScope - object scope to start the search (NULL means root)
* puipns -> to hold the pnsobj address if found
* pns -> buffer to hold the object found
* dwfNS - flags
*
* EXIT-SUCCESS
* returns DBGERR_NONE
* EXIT-FAILURE
* returns DBGERR_ code
*/
LONG LOCAL GetNSObj(PSZ pszObjPath, PNSOBJ pnsScope, PULONG_PTR puipns,
PNSOBJ pns, ULONG dwfNS)
{
LONG rc = DBGERR_NONE;
BOOLEAN fSearchUp = (BOOLEAN)(!(dwfNS & NSF_LOCAL_SCOPE) &&
(pszObjPath[0] != '\\') &&
(pszObjPath[0] != '^') &&
(STRLEN(pszObjPath) <= sizeof(NAMESEG)));
BOOLEAN fMatch = TRUE;
PSZ psz;
NSOBJ NSObj, NSChildObj;
if (*pszObjPath == '\\')
{
psz = &pszObjPath[1];
pnsScope = NULL;
}
else
{
for (psz = pszObjPath;
(*psz == '^') && (pnsScope != NULL) &&
(pnsScope->pnsParent != NULL);
psz++)
{
if (!ReadMemory((ULONG_PTR)pnsScope->pnsParent,
&NSObj,
sizeof(NSObj),
NULL))
{
DBG_ERROR(("failed to read parent object at %x",
pnsScope->pnsParent));
rc = DBGERR_CMD_FAILED;
break;
}
else
{
pnsScope = &NSObj;
}
}
if ((rc == DBGERR_NONE) && (*psz == '^'))
{
if (dwfNS & NSF_WARN_NOTFOUND)
{
DBG_ERROR(("object %s not found", pszObjPath));
}
rc = DBGERR_CMD_FAILED;
}
}
if ((rc == DBGERR_NONE) && (pnsScope == NULL))
{
if ((*puipns = READSYMULONGPTR("gpnsNameSpaceRoot")) == 0)
{
DBG_ERROR(("failed to get root object address"));
rc = DBGERR_CMD_FAILED;
}
else if (!ReadMemory(*puipns, &NSObj, sizeof(NSObj), NULL))
{
DBG_ERROR(("failed to read NameSpace root object at %x", *puipns));
rc = DBGERR_CMD_FAILED;
}
else
{
pnsScope = &NSObj;
}
}
while ((rc == DBGERR_NONE) && (*psz != '\0'))
{
if (pnsScope->pnsFirstChild == NULL)
{
fMatch = FALSE;
}
else
{
PSZ pszEnd = STRCHR(psz, '.');
ULONG dwLen = (ULONG)(pszEnd? (pszEnd - psz): STRLEN(psz));
if (dwLen > sizeof(NAMESEG))
{
DBG_ERROR(("invalid name path %s", pszObjPath));
rc = DBGERR_CMD_FAILED;
}
else
{
NAMESEG dwName = NAMESEG_BLANK;
BOOLEAN fFound = FALSE;
ULONG_PTR uip;
ULONG_PTR uipFirstChild = (ULONG_PTR)pnsScope->pnsFirstChild;
MEMCPY(&dwName, psz, dwLen);
//
// Search all siblings for a matching NameSeg.
//
for (uip = uipFirstChild;
(uip != 0) &&
ReadMemory(uip, &NSChildObj, sizeof(NSObj), NULL);
uip = ((ULONG_PTR)NSChildObj.list.plistNext ==
uipFirstChild)?
0: (ULONG_PTR)NSChildObj.list.plistNext)
{
if (NSChildObj.dwNameSeg == dwName)
{
*puipns = uip;
fFound = TRUE;
NSObj = NSChildObj;
pnsScope = &NSObj;
break;
}
}
if (fFound)
{
psz += dwLen;
if (*psz == '.')
{
psz++;
}
}
else
{
fMatch = FALSE;
}
}
}
if ((rc == DBGERR_NONE) && !fMatch)
{
if (fSearchUp && (pnsScope->pnsParent != NULL))
{
if (!ReadMemory((ULONG_PTR)pnsScope->pnsParent,
&NSObj,
sizeof(NSObj),
NULL))
{
DBG_ERROR(("failed to read parent object at %x",
pnsScope->pnsParent));
rc = DBGERR_CMD_FAILED;
}
else
{
fMatch = TRUE;
pnsScope = &NSObj;
}
}
else
{
if (dwfNS & NSF_WARN_NOTFOUND)
{
DBG_ERROR(("object %s not found", pszObjPath));
}
rc = DBGERR_CMD_FAILED;
}
}
}
if (rc != DBGERR_NONE)
{
*puipns = 0;
}
else if (pns != NULL)
{
MEMCPY(pns, pnsScope, sizeof(NSObj));
}
return rc;
} //GetNSObj
/***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)
{
ULONG dwLen;
UCHAR bFollowCnt, i;
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;
return dwLen;
} //ParsePackageLen
/***LP NameSegString - convert a NameSeg to an ASCIIZ stri
*
* ENTRY
* dwNameSeg - NameSeg
*
* EXIT
* returns string
*/
PSZ LOCAL NameSegString(ULONG dwNameSeg)
{
static char szNameSeg[sizeof(NAMESEG) + 1] = {0};
STRCPYN(szNameSeg, (PSZ)&dwNameSeg, sizeof(NAMESEG));
return szNameSeg;
} //NameSegString