📄 tsrlist.c
字号:
strcpy (pTsrStruct[wIndex].szTsrName, pszDosSystemArea);
pTsrStruct[wIndex].szParameters[0] = '\0';
}
}
else
{
strcpy (pTsrStruct[wIndex].szTsrName, pszDosSystemArea);
pTsrStruct[wIndex].szParameters[0] = '\0';
}
}
else
{
/* If the PSP == the parent's PSP, it's COMMAND.COM */
if (fpPspAddress == fpParentPspAddress)
strcpy (pTsrStruct[wIndex].szTsrName, pszCommandCom);
else
{
/* Otherwise, we have to find the name. First, search */
/* in the environment area. */
CHAR chEnvironName[80]; /* Buffer for storing what the */
/* environment claims the is */
/* the name of the TSR */
fwWordPointer = (WORD FAR *) (fpPspAddress + 0x002C);
fpTsrName = (CHAR FAR *) ((DWORD) *fwWordPointer << 16);
/* The name of the program that owns this MCB is located */
/* 2 bytes after 2 zero bytes and a word count. Loop */
/* through the environment block until 2 back-to-back */
/* zero bytes are located. */
while (!(fpTsrName[0] == 0 && fpTsrName[1] == 0))
++fpTsrName;
fpTsrName += 4;
/* fpTsrName is now pointing to the fully qualified path */
/* to the program name. Parse for just the program name. */
for (i = 0; i < MAX_TSR_NAME - 1 &&
*fpTsrName > ' ' &&
*fpTsrName < 127; ++fpTsrName)
{
if (*fpTsrName == '\\')
i = 0;
else
chEnvironName[i++] = *fpTsrName;
}
/* If this was the real name, it should end with a zero */
/* byte. If it was garbage, we should have dropped out */
/* because fpTsrName pointed to something other than a */
/* zero byte, or the length of the string is zero. */
if (*fpTsrName == '\0')
chEnvironName[i] = '\0';
else
chEnvironName[0] = '\0';
/* The name from the environment is now ready. Next, */
/* get the MCB owner (DOS 4.0 and above). If the MCB */
/* owner is the same as the beginning of the name from */
/* the environment, use chEnvironName. Otherwise, use */
/* the MCB name. */
if (wDosMajor < 4)
{
/* If there is no name, put in "???" */
if (strlen (chEnvironName) == 0)
strcpy (pTsrStruct[wIndex].szTsrName, "???");
else
strcpy (pTsrStruct[wIndex].szTsrName, chEnvironName);
}
else
{
/* Obtain the program name from the MCB */
fpTsrName = fpMcbHeader + 8;
for (i = 0; i < 8 &&
*fpTsrName > ' ' &&
*fpTsrName < 127 &&
*fpTsrName == (CHAR) toupper (*fpTsrName);
++i, ++fpTsrName)
{
pTsrStruct[wIndex].szTsrName[i] = *fpTsrName;
}
pTsrStruct[wIndex].szTsrName[i] = '\0';
/* Determine if this is a valid program name. If we */
/* have not taken 8 characters from the MCB, we */
/* should have run into a zero byte (the name is */
/* null terminated if there are less than 8 */
/* characters). */
if (i < 8 && (*fpTsrName != '\0' ||
pTsrStruct[wIndex].szTsrName[0] == '\0'))
{
/* Use the environment name */
strcpy (pTsrStruct[wIndex].szTsrName, chEnvironName);
}
/* The MCB contains a valid name. Check to see if the */
/* environment contains a more complete name (ie, */
/* the environment contains an extention, the MCB */
/* does not. */
else if (strnicmp (chEnvironName,
pTsrStruct[wIndex].szTsrName,
strlen (pTsrStruct[wIndex].szTsrName)) == 0)
{
strcpy (pTsrStruct[wIndex].szTsrName, chEnvironName);
}
if (strnicmp (pszCommand, pTsrStruct[wIndex].szTsrName,
strlen (pszCommand)) == 0)
{
/* The word "command" was found, put COMMAND.COM */
/* into the TSR Name field. */
strcpy (pTsrStruct[wIndex].szTsrName, pszCommandCom);
}
if (pTsrStruct[wIndex].szTsrName[0] == '\0')
{
/* A valid program name could not be found */
strcpy (pTsrStruct[wIndex].szTsrName, "???");
}
}
}
/* Get the command line parameters */
fpCommandLine = fpPspAddress + 0x0080;
/* The first byte is the number of characters in the */
/* command line. */
wCharCount = fpCommandLine[0];
if (wCharCount > MAX_TSR_CMD_LINE - 1)
wCharCount = MAX_TSR_CMD_LINE - 1;
++fpCommandLine;
for (i = 0; i < wCharCount &&
fpCommandLine[i] >= ' ' &&
fpCommandLine[i] <= 127; ++i)
pTsrStruct[wIndex].szParameters[i] = fpCommandLine[i];
pTsrStruct[wIndex].szParameters[i] = '\0';
}
/* Determine if this was the last MCB */
if (*fpMcbHeader == 'Z')
fEndOfList = TRUE;
else
{
/* Point to the next MCB */
dwNextMcbHeader = (DWORD) fpMcbHeader +
((DWORD) (wMcbParagraphs + 1) << 16);
fpMcbHeader = (CHAR FAR *) dwNextMcbHeader;
}
}
/* Set the last record to zeroes */
pTsrStruct[wIndex].wAddress = 0;
pTsrStruct[wIndex].dwBlockSize = 0;
pTsrStruct[wIndex].szTsrName[0] = '\0';
pTsrStruct[wIndex].szParameters[0] = '\0';
/* Set the UMB/DOS MCB chain back to normal */
LinkUmbToDosChain (FALSE);
return (FALSE);
}
/*********************************************************************
* SprintTsrInfo - Put TSR program information into a set of strings
* to be printed or displayed.
* fIncludeParms - TRUE if command line parameters are to be included.
*
* Returns: NULL if an error occured.
*********************************************************************/
QSZ * SprintTsrInfo (TSR_PROGRAMS_STRUCT *pTsrStruct,
BOOL fIncludeParms)
{
WORD wNmbrStrings; /* Number of strings */
WORD wNmbrChars; /* Number of characters in the strings */
WORD wUnderlineLength; /* Length of the underline string */
WORD wIndex; /* Index to the structure of TSR data */
WORD i; /* Looping variable */
QSZ *pqszStrings = NULL; /* Location for storing string pointers */
/* Calculate the amount of space required for the strings */
wUnderlineLength = strlen (pszTsrUnderline);
if (fIncludeParms)
{
wNmbrChars = strlen (pszTsrHeader) + 1 +
wUnderlineLength + 1 +
(wTsrCount * (wUnderlineLength + 1));
if (wNmbrChars > _memmax() - 100)
fIncludeParms = FALSE;
}
if (fIncludeParms == FALSE)
wNmbrChars = strlen (pszTsrHeader) + 1 +
wUnderlineLength + 1 +
(wTsrCount * (TSR_CMD_LINE_COL + 1));
/* The underline string is expected to be as long as a line of */
/* TSR program info. */
wNmbrStrings = wTsrCount + 3;
/* "+ 3" is for the header line, the underline, and the NULL */
/* pointer at the end of the array. */
/* Allocate space for the pointer area and string area */
pqszStrings = AllocStringSpace (wNmbrStrings, wNmbrChars);
if (pqszStrings == NULL)
return (NULL);
/* Put the first two strings in place */
Qstrcpy (pqszStrings[0], pszTsrHeader);
pqszStrings[1] = pqszStrings[0] + Qstrlen (pqszStrings[0]) + 1;
Qstrcpy (pqszStrings[1], pszTsrUnderline);
pqszStrings[2] = pqszStrings[1] + wUnderlineLength + 1;
/* Put the TSR information in place */
for (i = 2, wIndex = 0;
!(pTsrStruct[wIndex].wAddress == 0 &&
pTsrStruct[wIndex].dwBlockSize == 0);
++i, ++wIndex)
{
WORD wLength; /* Current length of string */
CHAR chBuffer[80]; /* Buffer for string data */
/* Fill the line with spaces */
Qmemset (pqszStrings[i], ' ', wUnderlineLength);
pqszStrings[i][wUnderlineLength] = '\0';
/* TSR Name */
Qstrcpy (pqszStrings[i], pTsrStruct[wIndex].szTsrName);
wLength = Qstrlen (pqszStrings[i]);
pqszStrings[i][wLength] = ' ';
/* Size */
wLength = sprintf (chBuffer, "%6lu",
pTsrStruct[wIndex].dwBlockSize);
Qstrcpy (&pqszStrings[i][TSR_SIZE_COL], chBuffer);
pqszStrings[i][TSR_SIZE_COL + wLength] = ' ';
/* Address */
wLength = sprintf (chBuffer, "%04X", pTsrStruct[wIndex].wAddress);
Qstrcpy (&pqszStrings[i][TSR_ADDRESS_COL], chBuffer);
pqszStrings[i][TSR_ADDRESS_COL + wLength] = ' ';
/* Command line parameters */
if (fIncludeParms)
Qstrcpy (&pqszStrings[i][TSR_CMD_LINE_COL],
pTsrStruct[wIndex].szParameters);
/* Set the next pointer */
PrepNextString (pqszStrings, i);
}
/* Set the last pointer to NULL */
pqszStrings[i] = NULL;
/* Return the pointer to pqszStrings */
return (pqszStrings);
}
/*********************************************************************
* FindFirstMcbHeader - Finds the pointer to the first memory control
* block (MCB).
*
* Returns: Far pointer to the first MCB.
*********************************************************************/
CHAR FAR * FindFirstMcbHeader (VOID)
{
union REGS regsIn, regsOut; /* Register structures for int86x call */
struct SREGS sregs; /* Segment registers for int86x call */
WORD wMcbSegment = 0; /* Segment of first MCB */
WORD FAR *fwWordPointer = NULL; /* A far pointer to a WORD */
/* Get the address of the start of DOS' list of lists (ES:BX) */
regsIn.h.ah = 0x52;
int86x (0x21, ®sIn, ®sOut, &sregs);
/* Get first MCB Segment */
fwWordPointer = (WORD FAR *)
((((long) (sregs.es) << 16) + (long) (regsOut.x.bx)) - 2);
wMcbSegment = *fwWordPointer;
/* Return pointer to the first MCB */
return ((CHAR FAR *) ((DWORD) wMcbSegment << 16));
}
/*********************************************************************
* LinkUmbToDosChain - Links or unlinks UMBs to the DOS memory control
* block chain.
* fLinkFlag - TRUE - Link UMBs to the DOS MCB chain.
* FALSE - Set the chain back to the default.
*********************************************************************/
VOID LinkUmbToDosChain (BOOL fLinkFlag)
{
union REGS regsin, regsout; /* Register structs for int86 call */
static BOOL fDefaultLink = 0xFFFF; /* Set to DOS Default of UMBs linked */
/* or unlinked */
/* Are we running under a valid version of DOS */
if (wDosMajor >= 5 && wDosMajor < 10)
{
/* Set the default, if necessary */
if (fDefaultLink == 0xFFFF)
{
regsin.x.ax = 0x5802;
int86 (0x21, ®sin, ®sout);
if (regsout.x.cflag == 0)
fDefaultLink = (BOOL) regsout.h.al;
else
return;
}
/* Now, set the link as per the request */
regsin.x.ax = 0x5803;
if (fLinkFlag)
{
/* Link the UMB chain to the DOS MCB chain */
regsin.x.bx = 0x0001;
int86 (0x21, ®sin, ®sout);
}
else
{
/* Set the UMB chain link to the default state */
regsin.x.bx = fDefaultLink;
int86 (0x21, ®sin, ®sout);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -