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

📄 membase.c

📁 DOS 源代码 系列之 command 源码
💻 C
📖 第 1 页 / 共 4 页
字号:
;/*
; *                      Microsoft Confidential
; *                      Copyright (C) Microsoft Corporation 1988 - 1991
; *                      All Rights Reserved.
; */

/*
 * MEMBASE.C - MEM routines for determining and displaying memory usage
 *             for conventional memory.
 */

#include "stdio.h"
#include "dos.h"
#include "string.h"
#include "stdlib.h"
#include "msgdef.h"
#include "version.h"
#include "mem.h"

#define EMSGetHandleName 0x5300 	/* get handle name function */
#define EMSGetHandlePages 0x4c00	/* get handle name function */
#define EMSCODE_83	0x83		/* handle not found error */
#define EMSMaxHandles	256		/* max number handles */

/*---------------------------------------------------------------------------*/

	    /*
	     * DataLevel:  0 -     Print nothing here
	     *             1 - /C: Print nothing here
	     *             2 - /D: Print everything available
	     *             3 - /F: Print any line with Owner == 0
	     *             4 - /M: Print any line with OwnerName == ModName
	     *
	     * modulesize, below, is only used with options /F and /M.
	     *
	     */

long   modulesize = 0L;            /* Increases... 0== haven't started. */
char  *gpszDevDriver = NULL;
char   Out_Str1[64];
char   Out_Str2[64];
extern unsigned int MaxMin[2];
int   HandleIndex;		      /* used to step through emm386 handles */
char  HandleName[9];		      /* save area for emm386 handle name */

#define K384   (long)(393216)  // 384k, the size of the upper-memory segment
#define ONEMEG (long)(1048576) // 1MB

unsigned int DisplayBaseDetail()
{
   char   temp[128], t2[128];
   struct ARENA far *ThisArenaPtr;
   struct ARENA far *NextArenaPtr;
   struct ARENA far *ThisConfigArenaPtr;
   struct ARENA far *NextConfigArenaPtr;

   struct DEVICEHEADER far *ThisDeviceDriver;

   int   SystemDataType;
   char	 SystemDataOwner[64];

   unsigned long far *UMB_Head_ptr;
   unsigned far *EnvironmentSegmentPtr;

   unsigned int long    Out_Var1;
   unsigned int long    Out_Var2;
   unsigned int long    Org_IOsize;
   unsigned int long    Org_IOaddr;
   unsigned int long    umb_numb = 0L;

   InRegs.h.ah = (unsigned char) 0x52;
   intdosx(&InRegs,&OutRegs,&SegRegs);

   FP_SEG(SysVarsPtr)   = FP_SEG(UMB_Head_ptr) = SegRegs.es;
   FP_OFF(SysVarsPtr)   = OutRegs.x.bx;

   FP_OFF(UMB_Head_ptr) = 0x8c;          /* ptr to UMB_HEAD in DOS Data */ 
   UMB_Head = (*UMB_Head_ptr) & 0xFFFF;

   if (DataLevel == 2)
      {
      mprintf (NewLineMsg, "");
      mprintf (ConvMemDet, "");
      mprintf (NewLineMsg, "");
      mprintf (Title1Msg,  "");
      mprintf (Title2Msg,  "");
      }

   if (DataLevel == 3)
      {
      mprintf (NewLineMsg,    "");
      mprintf (FreeConvMsg,   "");
      mprintf (NewLineMsg,    "");
      mprintf (FreeTitleMsg,  "");
      mprintf (FreeUScoreMsg, "");
      }

   InRegs.h.ah = (unsigned char) 0x30;
   intdos(&InRegs, &OutRegs);

   if ( (OutRegs.h.al != (unsigned char) 3) ||
        (OutRegs.h.ah < (unsigned char) 40) )
      {
      UseArgvZero = TRUE;
      }
   else
      {
      UseArgvZero = FALSE;
      }

		       /* Display stuff below DOS  */

   Out_Var1 = 0l;
   Out_Var2 = 0x3FFl;
   if (AddMem_to_Table (8, Out_Var1, umb_numb, Out_Var2-16))  return 1;
   DoMainLine (8,&Out_Var1,BlankMsg,&Out_Var2,InterruptVectorMsg,&umb_numb);

   Out_Var1 = 0x40l;
   Out_Var2 = 0xFFl;
   if (AddMem_to_Table (8, Out_Var1, umb_numb, Out_Var2-16))  return 1;
   DoMainLine(8,&Out_Var1,BlankMsg,&Out_Var2,ROMCommunicationAreaMsg,&umb_numb);

   Out_Var1 = 0x50l;
   Out_Var2 = 0x1FFl;
   if (AddMem_to_Table (8, Out_Var1, umb_numb, Out_Var2-16))  return 1;
   DoMainLine(8,&Out_Var1,BlankMsg,&Out_Var2,DOSCommunicationAreaMsg,&umb_numb);

	      /* Display the BIO data location and size */

   Out_Var1 = 0x70l;
   Out_Var2 = (long) (FP_SEG(SysVarsPtr) - 0x70)*16L - 16L;
   if (AddMem_to_Table (8, Out_Var1, umb_numb, Out_Var2))  return 1;
   DoMainLine (8, &Out_Var1, IbmbioMsg, &Out_Var2, SystemDataMsg, &umb_numb);

	  /* Display the Base Device Driver Locations and Sizes */

     /*********************************************************************/
     /* to do this get the starting address of the internal driver header */
     /* chain. Start from the first header and get the address of the     */
     /* first header.  Display the driver name and address by calling     */
     /* "DISPLAYDEVICEDRIVER".  Repeat this for next driver on the chain  */
     /* until the last driver.  Note that driver name is in the header.   */
     /* The driver header addrs is in the system variable table from      */
     /* INT 21H fun 52H call.                                             */
     /*********************************************************************/

   BlockDeviceNumber = 0;

   if (DataLevel == 2)
      {
      for (ThisDeviceDriver = SysVarsPtr->DeviceDriverChain;
	   (FP_OFF(ThisDeviceDriver) != 0xFFFF);
	   ThisDeviceDriver = ThisDeviceDriver->NextDeviceHeader)
	 {
	 if ( FP_SEG(ThisDeviceDriver) < FP_SEG(SysVarsPtr) )
	    {
	    strcpy (temp, GetDeviceDriver (ThisDeviceDriver));
	    mprintf (DeviceLineMsg, "%-8c%-m", temp, SystemDeviceDriverMsg);
	    }
	 }
      }

	      /* Display the DOS data location and size */

   FP_SEG(ArenaHeadPtr) = FP_SEG(SysVarsPtr);         /* ;an004; */
   FP_OFF(ArenaHeadPtr) = FP_OFF(SysVarsPtr) - 2;     /* ;an004; */
   FP_SEG(ThisArenaPtr) = *ArenaHeadPtr;              /* ;an004; */
   FP_OFF(ThisArenaPtr) = 0;                          /* ;an004; */

   Out_Var1 = (long) FP_SEG(SysVarsPtr);
   Out_Var2 = (long) (AddressOf((char far *)ThisArenaPtr) - Out_Var1)*16L -16L;
   if (AddMem_to_Table (8, Out_Var1, umb_numb, Out_Var2))  return (1);
   DoMainLine (8, &Out_Var1, IbmdosMsg, &Out_Var2, SystemDataMsg, &umb_numb);

		    /* Display the memory data */

/******************************************************************************
/*
/* IO.SYS data area contains BUFFERS, FCBs, LAST DRIVE etc.  They are contained
/* in a one huge memory block.  This block has a seg iD 0008.  This seg ID can
/* be found from the block header owner area.  This seg id 0008:0000
/* points to the buffer table as shown below.  If seg id is 0008:000, then
/* using the seg id find the table.  Each entry is contained in a sub block
/* within the main block.  Each sub block has header and this header contains
/* id such as B for BUFFER,  X for FCBs,  I for IFS,  D for external device
/* drivers.  Go through the sub blocks and display the name ans size. that's it.
/*
/* If the block contains D, then it contains external drivers.  The driver name
/* is not in the sub block.  So we have to find the driver name from the driver
/* header chain.  To do this get the address of the driver chain from system
/* variable table from INT 21H FN 52H call.  Go through the chain and find out
/* the name.  Display name from the header and the size we got from the sub
/* block.
/*
/*
/* After this main block, comes other buffer blocks which contains programs
/* such as command.com, doscolor, even MEM.  From these blocks, get the program
/* name and the size and display them too.
/*
/* 0008:000->------------------          -------------------
/*           | BUFFERS        | -------->|B (signature)    | Block header
/*           ------------------          -------------------
/*           | FCBs           | --       |                 |
/*           ------------------   |      | Buffers data    |
/*           | IFSs           |   |      |                 |
/*           ------------------   |      |                 |
/*           | LAST DRIVE     |   |      |                 |
/*           ------------------   |      -------------------
/*           | EXTERN DRIVER 1|   |
/*           ------------------   |          -------------------
/*           | EXTERN DRIVER 2|   | -------->|X (signature)    | Block header
/*           ------------------              -------------------
/*           | EXTERN DRIVER 3|              |                 |
/*           ------------------              | Buffers data    |
/*                                           |                 |
/*                                           |                 |
/*                                           |                 |
/*                                           -------------------
/*
/* For DOS 5.0, there are some additions to the above.	Basically, we have
/* three possible memory maps, to wit:
/*
/*    DOS Loads Low			     DOS loads high
/*    70:0 - BIOS data			     70:0 - BIOS data
/*	     DOS data				    DOS data
/*	     BIOS + DOS code			    Sysinit data (arena name SD)
/*	       (arena owner 8, name "SC")	    VDisk header (arena name SC)
/*	     Sysinit data (arean owner 8, name SD)
/*
/*    DOS tries to load high but fails
/*    70:0 - BIOS data
/*	     DOS data
/*	     Sysinit data (arena name SD)
/*	     DOS + BIOS code (arena name SC)
/*
/*    We have to detect the special arena ownership marks and display them
/*    correctly.  Everything after DOS and BIOS data should have an arena header
/******************************************************************************/

   for (;;)
      {

#ifdef JAPAN
      if (ThisArenaPtr->Owner == 8 || ThisArenaPtr->Owner == 9)
#else
      if (ThisArenaPtr->Owner == 8)
#endif
	 {

	 FP_SEG(NextArenaPtr)=FP_SEG(ThisArenaPtr) +ThisArenaPtr->Paragraphs +1;
	 FP_OFF(NextArenaPtr)=0;

	 Out_Var1 = AddressOf((char far *)ThisArenaPtr);
	 Out_Var2 = (long) (ThisArenaPtr -> Paragraphs) * 16l;
	 if (ThisArenaPtr->OwnerName[0] == 'S' &&
	     ThisArenaPtr->OwnerName[1] == 'C')
	    {
	            /* display message for BIOS and DOS code */

	    if ((long)FP_SEG (ThisArenaPtr) >= (long)UMB_Head)
	       {
	       umb_numb++;

	       if (DataLevel == 2)
		  {
		  mprintf (NewLineMsg, "");

	          if (umb_numb == 1)
		     {
		     mprintf(UpperMemDet, "");
		     mprintf(NewLineMsg,  "");
		     mprintf(Title1AMsg,  "");
		     mprintf(Title2AMsg,  "");
		     }
                  }
	       }
	    else
	       {
	       if (AddMem_to_Table (8,Out_Var1,umb_numb,Out_Var2))
	          return(1);

	       DoMainLine (8, &Out_Var1, IbmdosMsg, &Out_Var2,
		              SystemProgramMsg, &umb_numb);
	       }
	    }
	 else if (ThisArenaPtr->OwnerName[0] == 'H')
	    {

	    if (AddMem_to_Table (0, Out_Var1, umb_numb, Out_Var2))
	       return(1);

/*
 * this block has been hidden via loadhigh for loading mem ... display it as
 * LOADHIGH / Temporarily Restricted
 *
 *          DoMainLine(0,&Out_Var1,LoadHighMsg,&Out_Var2,HiddenMsg,&umb_numb);
 *
 * That line removed in favor of making it all look more like free memory:
 *
 */

            DoMainLine (0,&Out_Var1,LoadHighMsg,&Out_Var2,FreeMsg,&umb_numb); 

	    }
	 else
	    {

/*
 * display message for data (8+SD)
 *
 */

            Org_IOaddr = Out_Var1;
            Org_IOsize = Out_Var2;

	    DoMainLine(8,&Out_Var1,IbmbioMsg,&Out_Var2,SystemDataMsg,&umb_numb);

	    FP_SEG(ThisConfigArenaPtr) = FP_SEG(ThisArenaPtr) +1;
	    FP_OFF(ThisConfigArenaPtr) = 0;

	    while ( (FP_SEG(ThisConfigArenaPtr) > FP_SEG(ThisArenaPtr)) &&
		    (FP_SEG(ThisConfigArenaPtr) < FP_SEG(NextArenaPtr)))
	       {

	       if (ThisConfigArenaPtr->Signature=='D' ||
	           ThisConfigArenaPtr->Signature=='I')
		  {
		  strcpy (SystemDataOwner, OwnerOf (ThisConfigArenaPtr));
		  }
	       else
		  {
		  strcpy (SystemDataOwner, " ");
		  }

	       switch (ThisConfigArenaPtr->Signature)
		  {
		  case 'B':  SystemDataType = ConfigBuffersMsg;          break;
		  case 'D':  SystemDataType = InstalledDeviceDriverMsg;  break;
		  case 'F':  SystemDataType = ConfigFilesMsg;            break;
		  case 'I':  SystemDataType = ConfigIFSMsg;              break;
		  case 'L':  SystemDataType = ConfigLastDriveMsg;        break;
		  case 'S':  SystemDataType = ConfigStacksMsg;           break;
		  case 'T':  SystemDataType = ConfigInstallMsg;          break;
		  case 'X':  SystemDataType = ConfigFcbsMsg;             break;
		  default:   SystemDataType = BlankMsg;                  break;
		  }

/*
 *  Found one, now display the owner name and size
 *
 */

	       if (SystemDataType != BlankMsg)
		  {
		  Out_Var1 = ((long) ThisConfigArenaPtr -> Paragraphs) * 16l;
		  sprintf (temp, "(%ldK)", toK(Out_Var1));
		  NextConfigArenaPtr = ThisConfigArenaPtr;
		  FP_SEG(NextConfigArenaPtr)+=NextConfigArenaPtr->Paragraphs+1;
		  if (ThisConfigArenaPtr->Signature == (char)'D')
		     {
		     FP_SEG(ThisDeviceDriver) = FP_SEG(ThisConfigArenaPtr) + 1;
		     FP_OFF(ThisDeviceDriver) = 0;

		     strcpy (t2, GetDeviceDriver (ThisDeviceDriver));

		     ThisDeviceDriver = ThisDeviceDriver->NextDeviceHeader;
		     }
		  else
		     {
		     strcpy (SystemDataOwner, DriverData (ThisConfigArenaPtr));
                     strcpy (t2,              " ");
		     }

		 if (ThisConfigArenaPtr->Signature=='D' ||
		     ThisConfigArenaPtr->Signature=='I')
		     {
		     Org_IOsize -= Out_Var1;
		     gpszDevDriver = SystemDataOwner;
		     AddMem_to_Table (7, Org_IOaddr, umb_numb, Out_Var1);
		     DoMainLine (7, &Org_IOaddr, 0, &Out_Var1,
		                 SystemDataType, &umb_numb);
		     }

		  if (DataLevel == 2)
		     {
		     mprintf (DriverLineMsg, "%8ld%7c%-8c%-m%-c",
			&Out_Var1, temp, t2, SystemDataType, SystemDataOwner);
		     }
		  }

	       FP_SEG(ThisConfigArenaPtr) += ThisConfigArenaPtr->Paragraphs +1;
	       }

/*

⌨️ 快捷键说明

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