⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tsrlist.c

📁 Dos6.0
💻 C
📖 第 1 页 / 共 2 页
字号:
                  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, &regsIn, &regsOut, &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, &regsin, &regsout);

          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, &regsin, &regsout);
        }
      else
        {
          /* Set the UMB chain link to the default state */
          regsin.x.bx = fDefaultLink;
          int86 (0x21, &regsin, &regsout);
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -