Windows2000/private/windbg64/windbg/pidtid.c
2020-09-30 17:12:32 +02:00

547 lines
11 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
pidtid.c
Author:
Griffith Wm. Kadnier (v-griffk)
Environment:
Win32 - User
--*/
#include "precomp.h"
#pragma hdrstop
/****************************** DATA **************************************/
static LPPD LppdHead = NULL;
static int ipid = 0;
/****************************** CODE **************************************/
VOID SetIpid(int i)
{
ipid = i;
}
VOID RecycleIpid1(void)
{
if (LppdHead && LppdHead->pstate != psDestroyed && !LppdHead->lppdNext&& ipid == 2)
{
ipid = 1;
}
}
LPPD GetLppdHead(void)
/*++
Routine Description:
Retrieves head of LPPD chain.
Return Value:
Pointer to first PD in chain
--*/
{
return LppdHead;
}
LPPD CreatePd(HPID hpid)
/*++
Routine Description:
This function will create a process descriptor block, fill in
the defaults for the fields and return a pointer to the descriptor
block. No attempts are made to verify that the hpid (handle to
process identifier) passed in is correct in any way.
Arguments:
hpid - Handle to process in the OSDebug world
Return Value:
NULL on failure or a pointer to a PD structure
--*/
{
LPPD lppd;
LPPD lppdT;
/*
** first allocate and verify the allocation succeeded
*/
lppd = (LPPD) malloc(sizeof(PD));
if (lppd == NULL) {
return lppd;
}
memset(lppd, 0, sizeof(PD));
/*
** Now fill in the default set of values for the structure
** hpid == passed in value
** state == no program has yet been loaded here.
** lptdNext == No threads currently linked on this process.
*/
lppd->hpid = hpid;
lppd->pstate = psNoProgLoaded;
lppd->lptdList = NULL;
lppd->ctid = 0;
lppd->ipid = ipid++;
lppd->exceptionList=NULL;
lppd->lpBaseExeName = NULL;
lppd->fPrecious = FALSE;
lppd->fChild = FALSE;
lppd->fFrozen = FALSE;
/*
** Now append it to the list of process descriptors
*/
lppd->lppdNext = NULL;
lppdT = LppdHead;
if (lppdT == NULL) {
LppdHead = lppd;
} else {
while (lppdT->lppdNext) {
lppdT = lppdT->lppdNext;
}
lppdT->lppdNext = lppd;
}
/*
** Return the pointer to the process descriptor block allocated
*/
return(lppd);
} /* CreatePd() */
VOID
DestroyPd(
LPPD lppd,
BOOL fDestroyPrecious
)
/*++
Routine Description:
Remove a PD from the list and free it.
Arguments:
lppd - Supplies pointer to PD to be destroyed
Return Value:
None.
--*/
{
LPPD *lplppd;
/*
* Remove it from the chain
*/
for (lplppd = &LppdHead; *lplppd; lplppd = &((*lplppd)->lppdNext) ) {
if (*lplppd == lppd) {
if (lppd->lpBaseExeName) {
free(lppd->lpBaseExeName);
lppd->lpBaseExeName = NULL;
}
if (lppd->fPrecious && !fDestroyPrecious) {
lppd->pstate = psDestroyed;
} else {
*lplppd = lppd->lppdNext;
free(lppd);
}
break;
}
}
} /* DestroyPd() */
/*** LppdOfHpid
** Synopsis:
** lppd = LppdOfHpid(hpid)
** Entry:
** hpid - Process id handle to be found
** Returns:
** pointer to PD if hpid is found and NULL otherwise
** Description:
** This routine looks down the list of PDS looking for the specific
** hpid. If it is found then a pointer to that pd will be returned
** otherwise NULL is returned
*/
LPPD
LppdOfHpid(
HPID hpid
)
{
LPPD lppd = LppdHead;
while (lppd != NULL) {
if (lppd->hpid == hpid) {
break;
}
lppd = lppd->lppdNext;
}
return(lppd);
} /* LppdOfHpid() */
/*** LppdOfIpid
** Synopsis:
** lppd = LppdOfIpid(ipid)
** Entry:
** ipid - Internal index number of the process
** Returns:
** Pointer to process structure if one exists else NULL
** Description:
*/
LPPD
LppdOfIpid(
UINT ipid
)
{
LPPD lppd = LppdHead;
while (lppd != NULL) {
if (lppd->ipid == ipid) {
break;
}
lppd = lppd->lppdNext;
}
return lppd;
} /* LppdOfIpid() */
LPPD
ValidLppdOfIpid(
UINT ipid
)
/*++
Routine Description:
Look up LPPD by its index #, ignoring destroyed lppd's
Arguments:
ipid - ordinal number of process
Return Value:
LPPD or NULL
--*/
{
LPPD lppd;
for (lppd = LppdHead; lppd != NULL; lppd = lppd->lppdNext) {
if (lppd->pstate != psDestroyed && lppd->ipid == ipid) {
break;
}
}
return lppd;
}
BOOL
GetFirstValidPDTD(
LPPD *plppd,
LPTD *plptd
)
/*++
Routine Description:
Find first non-destroyed LPPD/LPTD pair in list
Arguments:
plppd - returns lppd
plptd - returns lptd
Return Value:
TRUE for success, FALSE of none found. Values pointed to by
args are not modified if search fails.
--*/
{
LPPD lppd;
for (lppd = LppdHead; lppd; lppd = lppd->lppdNext) {
if (lppd->pstate != psDestroyed && lppd->lptdList) {
*plppd = lppd;
*plptd = lppd->lptdList;
return TRUE;
}
}
return FALSE;
}
/*** CreateTd
** Synopsis:
** lptd = CreateTd(lppd, htid)
** Entry:
** lppd - Pointer to process descriptor block to create thread in
** htid - OSDebug thread handle to be added to process
** Returns:
** pointer to thread descriptor block on success, NULL on failure
** Description:
** This function will create a thread descriptor block for the
** osdebug handle to a thread. It will be added to the list of
** threads for the specified process descriptor block.
*/
LPTD
CreateTd(
LPPD lppd,
HTID htid
)
{
LPTD lptd;
LPTD lptd2;
/*
** First allocate and verify success
*/
lptd = (LPTD) malloc(sizeof(TD));
if (lptd == NULL)
return lptd;
memset(lptd, 0, sizeof(TD));
/*
** Now fill in the default set of values for a thread descriptor
*/
lptd->htid = htid;
lptd->lppd = lppd;
lptd->tstate = tsPreRunning;
lptd->itid = lppd->ctid++;
/*
** Now insert it in the thread list for the process
*/
lptd->lptdNext = NULL;
lptd2 = lppd->lptdList;
if (lptd2 == NULL) {
lppd->lptdList = lptd;
} else {
while (lptd2->lptdNext != NULL) {
lptd2 = lptd2->lptdNext;
}
lptd2->lptdNext = lptd;
}
/*
*/
return lptd;
} /* CreateTd() */
VOID
SetTdInfo(
LPTD lptd
)
{
// BUGBUG need portable structures here
BYTE buf[sizeof(IOCTLGENERIC)+sizeof(GET_TEB_ADDRESS)];
PIOCTLGENERIC pig = (PIOCTLGENERIC)&buf[0];
PGET_TEB_ADDRESS Gta = (PGET_TEB_ADDRESS)pig->data;
LPTD lptdSave;
DWORD dw;
if (g_contWorkspace_WkSp.m_bKernelDebugger) {
lptd->lpszTname = NULL;
lptd->TebBaseAddress = 0;
} else {
if (lptd->TebBaseAddress == 0) {
lptdSave = LptdCur;
LptdCur = lptd;
pig->ioctlSubType = IG_GET_TEB_ADDRESS;
pig->length = sizeof(GET_TEB_ADDRESS);
OSDSystemService( LppdCur->hpid,
lptd->htid,
(SSVC) ssvcGeneric,
(LPV)pig,
pig->length + sizeof(IOCTLGENERIC),
&dw
);
lptd->TebBaseAddress = Gta->Address;
lptd->lpszTname = GetLastFrameFuncName();
LptdCur = lptdSave;
}
}
}
VOID
SetPdInfo(
LPPD lppd
)
{
// BUGBUG Need portable structures here
BYTE buf[sizeof(IOCTLGENERIC)+sizeof(RTL_USER_PROCESS_PARAMETERS64)];
PIOCTLGENERIC pig = (PIOCTLGENERIC)&buf[0];
PRTL_USER_PROCESS_PARAMETERS64 Upp = (PRTL_USER_PROCESS_PARAMETERS64)pig->data;
DWORD dw;
XOSD xosd;
pig->ioctlSubType = IG_GET_PROCESS_PARAMETERS;
pig->length = sizeof(RTL_USER_PROCESS_PARAMETERS64);
OSDGetDebugMetric( lppd->hpid,
0,
mtrcProcessorType,
&lppd->mptProcessorType
);
if (!g_contWorkspace_WkSp.m_bKernelDebugger) {
xosd = OSDSystemService( lppd->hpid,
NULL,
(SSVC) ssvcGeneric,
(LPV)pig,
pig->length + sizeof(IOCTLGENERIC),
&dw
);
if (xosd == xosdNone) {
memcpy(&lppd->ProcessParameters, Upp, sizeof(RTL_USER_PROCESS_PARAMETERS64));
}
}
}
VOID DestroyTd(LPTD lptd)
{
LPPD lppd = lptd->lppd;
LPTD lptdT;
if (lppd->lptdList == lptd) {
lppd->lptdList = lptd->lptdNext;
} else {
lptdT = lppd->lptdList;
while (lptdT->lptdNext != lptd) {
lptdT = lptdT->lptdNext;
Assert(lptdT != NULL);
}
lptdT->lptdNext = lptd->lptdNext;
}
free(lptd);
} /* DestroyTd() */
/*** LptdOfLppdHtid
** Synopsis:
** lppd = LptdOfLppdHtid(lppd, htid)
** Entry:
** lppd - Process descripter table to look in for thread descriptor
** htid - thread id handle to be found
** Returns:
** pointer to TD if htid is found and NULL otherwise
** Description:
** This routine looks down the list of TDs looking for the specific
** htid. If it is found then a pointer to that td will be returned
** otherwise NULL is returned
*/
LPTD
LptdOfLppdHtid(
LPPD lppd,
HTID htid
)
{
LPTD lptd;
if (!lppd) {
return NULL;
}
lptd = lppd->lptdList;
while (lptd != NULL) {
if (lptd->htid == htid) {
return lptd;
}
lptd = lptd->lptdNext;
}
return(lptd);
} /* LptdOfLppdHtid() */
/*** LptdOfLppdItid
** Synopsis:
** lptd = LptdOfLppdItid(lppd, itid)
** Entry:
** lppd - pointer to process
** itid - index of thread
** Returns:
** pointer to thread if found else NULL
** Description:
** This function will locate a thread within the given process which
** has the correct thread id. This thread id is local to the shell
** of the debugger and is not the same as a Htid. If no such thread
** is found then NULL will be returned
*/
LPTD
LptdOfLppdItid(
LPPD lppd,
UINT itid
)
{
LPTD lptd = lppd->lptdList;
while (lptd != NULL) {
if (lptd->itid == itid)
return lptd;
lptd = lptd->lptdNext;
}
return lptd;
} /* LptdOfLppdItid() */