📄 membase.c
字号:
;/*
; * 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 + -