Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1056 lines
35 KiB

;/*
; * 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"
/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
/* go through the arena and print out the program name,size etc for /P switch */
/* but just keep storing them in a datastruct for later disp. for /C switch */
unsigned int DisplayBaseDetail()
{
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 int far *UMB_Head_ptr;
unsigned int long Out_Var1;
unsigned int long Out_Var2;
char Out_Str1[64];
char Out_Str2[64];
unsigned int msgno;
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;
if (!Classify)
Sub0_Message(NewLineMsg,STDOUT,Utility_Msg_Class);
if (DataLevel > 0)
{
if (!Classify) {
Sub0_Message(Title1Msg,STDOUT,Utility_Msg_Class);
Sub0_Message(Title2Msg,STDOUT,Utility_Msg_Class);
}
}
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 = 0x400l;
if (Classify) /* M003 */
/* classify this memory also as part of DOS */
{ if (AddMem_to_PSP(8,Out_Var1,Out_Var2)) return(1); }
else
Sub4_Message(MainLineMsg,
STDOUT,
Utility_Msg_Class,
&Out_Var1,
BlankMsg,
&Out_Var2,
InterruptVectorMsg);
Out_Var1 = 0x400l;
Out_Var2 = 0x100l;
if (Classify)
/* classify this memory also as part of DOS */
{ if (AddMem_to_PSP(8,Out_Var1,Out_Var2)) return(1); }
else
Sub4_Message(MainLineMsg,
STDOUT,
Utility_Msg_Class,
&Out_Var1,
BlankMsg,
&Out_Var2,
ROMCommunicationAreaMsg);
Out_Var1 = 0x500l;
Out_Var2 = 0x200l;
if (Classify)
/* classify this memory also as part of DOS */
{ if (AddMem_to_PSP(8,Out_Var1,Out_Var2)) return(1); }
else
Sub4_Message(MainLineMsg,
STDOUT,
Utility_Msg_Class,
&Out_Var1,
BlankMsg,
&Out_Var2,
DOSCommunicationAreaMsg);
/* Display the DOS data */
/* Display the BIO data location and size */
if (!Classify)
Sub0_Message(NewLineMsg,STDOUT,Utility_Msg_Class);
Out_Var1 = 0x700l;
Out_Var2 = (long) (FP_SEG(SysVarsPtr) - 0x70)*16l;
if (Classify)
/* classify this memory also as part of DOS */
{ if (AddMem_to_PSP(8,Out_Var1,Out_Var2)) return(1); }
else
Sub4_Message(MainLineMsg,
STDOUT,
Utility_Msg_Class,
&Out_Var1,
IbmbioMsg,
&Out_Var2,
SystemDataMsg);
/* 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;
for (ThisDeviceDriver = SysVarsPtr -> DeviceDriverChain;
(FP_OFF(ThisDeviceDriver) != 0xFFFF);
ThisDeviceDriver = ThisDeviceDriver -> NextDeviceHeader)
{ if ( FP_SEG(ThisDeviceDriver) < FP_SEG(SysVarsPtr) )
DisplayDeviceDriver(ThisDeviceDriver,SystemDeviceDriverMsg);
}
/* Display the DOS data location and size */
FP_SEG(ArenaHeadPtr) = FP_SEG(SysVarsPtr); /* ;an004; */
FP_OFF(ArenaHeadPtr) = FP_OFF(SysVarsPtr) - 2; /* ;an004; */
/* ;an004; */
FP_SEG(ThisArenaPtr) = *ArenaHeadPtr; /* ;an004; */
FP_OFF(ThisArenaPtr) = 0; /* ;an004; */
if (!Classify)
Sub0_Message(NewLineMsg,STDOUT,Utility_Msg_Class);
Out_Var1 = (long) FP_SEG(SysVarsPtr) * 16l;
Out_Var2 = (long) ((AddressOf((char far *)ThisArenaPtr)) - Out_Var1); /* ;ac004; */
if (Classify)
/* classify this memory also as part of DOS */
{ if (AddMem_to_PSP(8,Out_Var1,Out_Var2)) return(1); }
else
Sub4_Message(MainLineMsg,
STDOUT,
Utility_Msg_Class,
&Out_Var1,
IbmdosMsg,
&Out_Var2,
SystemDataMsg);
if (!Classify)
Sub0_Message(NewLineMsg,STDOUT,Utility_Msg_Class);
/* 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 all. */
/* */
/* 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 syster */
/* variable table from INT 21H FN 52H call. Go through the chain and findout */
/* 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
/******************************************************************************/
while (ThisArenaPtr -> Signature != (char) 'Z')
{
/* MSKK02 */
#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 (Classify)
/* classify this memory also as part of DOS */
{ if (AddMem_to_PSP(8,Out_Var1,Out_Var2)) return(1); }
else {
msgno = (FP_SEG(ThisArenaPtr) < UMB_Head) ? IbmdosMsg:SystemMsg;
Sub4_Message(MainLineMsg,
STDOUT,
Utility_Msg_Class,
&Out_Var1,
msgno,
&Out_Var2,
SystemProgramMsg);
Sub0_Message(NewLineMsg,STDOUT,Utility_Msg_Class);
}
}
else /* display message for data */
{
if (!Classify)
Sub4_Message(MainLineMsg,
STDOUT,
Utility_Msg_Class,
&Out_Var1,
#ifdef JAPAN
(ThisArenaPtr -> Owner == 8) ? IbmbioMsg : AdddrvMsg,
&Out_Var2,
(ThisArenaPtr -> Owner == 8) ? SystemDataMsg : ProgramMsg );
#else
IbmbioMsg,
&Out_Var2,
SystemDataMsg);
#endif
FP_SEG(ThisConfigArenaPtr) = FP_SEG(ThisArenaPtr) + 1;
FP_OFF(ThisConfigArenaPtr) = 0;
while ( (FP_SEG(ThisConfigArenaPtr) > FP_SEG(ThisArenaPtr)) &&
(FP_SEG(ThisConfigArenaPtr) < FP_SEG(NextArenaPtr)) )
{
strcpy(SystemDataOwner," ");
switch(ThisConfigArenaPtr -> Signature)
{
case 'B':
SystemDataType = ConfigBuffersMsg;
if (AddMem_to_PSP(8,((long)ThisConfigArenaPtr) <<4,((long)ThisConfigArenaPtr->Paragraphs <<4) +1)) return(1);
break;
case 'D':
SystemDataType = ConfigDeviceMsg;
if (AddMem_to_PSP(ThisConfigArenaPtr->Owner,((long)FP_SEG(ThisConfigArenaPtr)*16l) ,((long)ThisConfigArenaPtr->Paragraphs <<4) +1)) return(1);
strcpy(SystemDataOwner,OwnerOf(ThisConfigArenaPtr));
break;
case 'F':
SystemDataType = ConfigFilesMsg;
if (AddMem_to_PSP(8,((long)FP_SEG(ThisConfigArenaPtr) *16l),((long)ThisConfigArenaPtr->Paragraphs <<4) +1)) return(1);
break;
case 'I':
SystemDataType = ConfigIFSMsg;
strcpy(SystemDataOwner,OwnerOf(ThisConfigArenaPtr));
if (AddMem_to_PSP(ThisConfigArenaPtr->Owner,((long)ThisConfigArenaPtr) <<4,((long)ThisConfigArenaPtr->Paragraphs <<4) +1)) return(1);
break;
case 'L':
SystemDataType = ConfigLastDriveMsg;
if (AddMem_to_PSP(8,((long)ThisConfigArenaPtr) <<4,((long)ThisConfigArenaPtr->Paragraphs <<4) +1)) return(1);
break;
case 'S':
SystemDataType = ConfigStacksMsg;
if (AddMem_to_PSP(8,((long)ThisConfigArenaPtr) <<4,((long)ThisConfigArenaPtr->Paragraphs <<4) +1)) return(1);
break;
case 'T': /* gga */
SystemDataType = ConfigInstallMsg; /* gga */
if (AddMem_to_PSP(8,((long)ThisConfigArenaPtr) <<4,((long)ThisConfigArenaPtr->Paragraphs <<4) +1)) return(1);
break; /* gga */
case 'X':
SystemDataType = ConfigFcbsMsg;
if (AddMem_to_PSP(8,((long)ThisConfigArenaPtr) <<4,((long)ThisConfigArenaPtr->Paragraphs <<4) +1)) return(1);
break;
// NTVDM for special kbd\mouse drivers
case 'Q':
SystemDataType = SystemProgramMsg;
strcpy(SystemDataOwner,OwnerOf(ThisConfigArenaPtr));
if (AddMem_to_PSP(ThisConfigArenaPtr->Owner,((long)FP_SEG(ThisConfigArenaPtr)*16l) ,((long)ThisConfigArenaPtr->Paragraphs <<4) +1)) return(1);
break;
#ifdef JAPAN
case '?':
SystemDataType = DataMsg;
break;
#endif
default:
SystemDataType = BlankMsg;
if (AddMem_to_PSP(8,((long)ThisConfigArenaPtr) <<4,((long)ThisConfigArenaPtr->Paragraphs <<4) +1)) return(1);
break;
}
/****************************************************/
/* Found one, now display the owner name and size */
/****************************************************/
Out_Var1 = ((long) ThisConfigArenaPtr -> Paragraphs) * 16l;
if (!Classify)
Sub3_Message(DriverLineMsg,
STDOUT,
Utility_Msg_Class,
SystemDataOwner,
&Out_Var1,
SystemDataType );
NextConfigArenaPtr = ThisConfigArenaPtr;
FP_SEG(NextConfigArenaPtr) += NextConfigArenaPtr -> Paragraphs + 1;
if (ThisConfigArenaPtr -> Signature == (char) 'D')
{
FP_SEG(ThisDeviceDriver) = FP_SEG(ThisConfigArenaPtr) + 1;
FP_OFF(ThisDeviceDriver) = 0;
/* start MSKK bug fix - MSKK01 */
while ( (FP_SEG(ThisDeviceDriver) > FP_SEG(ThisConfigArenaPtr)) &&
(FP_SEG(ThisDeviceDriver) < FP_SEG(NextConfigArenaPtr)) ) {
DisplayDeviceDriver(ThisDeviceDriver,InstalledDeviceDriverMsg);
ThisDeviceDriver = ThisDeviceDriver -> NextDeviceHeader;
}
/* end MSKK bug fix - MSKK01 */
}
FP_SEG(ThisConfigArenaPtr) += ThisConfigArenaPtr -> Paragraphs + 1;
}
}
}
else {
/*******************************************************************************/
/* If not BIOS table, it is a program like MEM, etc. */
/* calculate the size of the block occupied by the program and display program */
/* name and size */
/*******************************************************************************/
Out_Var1 = AddressOf((char far *)ThisArenaPtr);
Out_Var2 = ((long) (ThisArenaPtr -> Paragraphs)) * 16l;
strcpy(Out_Str1,OwnerOf(ThisArenaPtr));
strcpy(Out_Str2,TypeOf(ThisArenaPtr));
if (Classify)
{ if (AddMem_to_PSP(ThisArenaPtr->Owner,Out_Var1,Out_Var2)) return(1); }
else
Sub4a_Message(MainLineMsg,
STDOUT,
Utility_Msg_Class,
&Out_Var1,
Out_Str1,
&Out_Var2,
Out_Str2);
}
FP_SEG(ThisArenaPtr) += ThisArenaPtr -> Paragraphs + 1;
}
Out_Var1 = AddressOf((char far *)ThisArenaPtr);
Out_Var2 = ((long) (ThisArenaPtr -> Paragraphs)) * 16l;
strcpy(Out_Str1,OwnerOf(ThisArenaPtr));
strcpy(Out_Str2,TypeOf(ThisArenaPtr));
if (Classify)
{ if (AddMem_to_PSP(ThisArenaPtr->Owner,Out_Var1,Out_Var2)) return(1); }
else
Sub4a_Message(MainLineMsg,
STDOUT,
Utility_Msg_Class,
&Out_Var1,
Out_Str1,
&Out_Var2,
Out_Str2);
return(0); /* end of MEM main routine */
}
/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
void DisplayDeviceDriver(ThisDeviceDriver,DeviceDriverType)
struct DEVICEHEADER far *ThisDeviceDriver;
int DeviceDriverType;
{
char LocalDeviceName[16];
int i;
if (DataLevel < 2) return;
if ( ((ThisDeviceDriver -> Attributes) & 0x8000 ) != 0 )
{ for (i = 0; i < 8; i++) LocalDeviceName[i] = ThisDeviceDriver -> Name[i];
LocalDeviceName[8] = NUL;
Sub2_Message(DeviceLineMsg,
STDOUT,
Utility_Msg_Class,
LocalDeviceName,
DeviceDriverType);
}
else {
if ((int) ThisDeviceDriver -> Name[0] == 1)
sprintf(&LocalDeviceName[0],SingleDrive,'A'+BlockDeviceNumber);
else sprintf(&LocalDeviceName[0],MultipleDrives,
'A'+BlockDeviceNumber,
'A'+BlockDeviceNumber + ((int) ThisDeviceDriver -> Name[0]) - 1);
Sub2_Message(DeviceLineMsg,
STDOUT,
Utility_Msg_Class,
LocalDeviceName,
DeviceDriverType);
BlockDeviceNumber += (int) (ThisDeviceDriver -> Name[0]);
}
return;
}
/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
void DisplayBaseSummary()
{
struct PSP_STRUC
{
unsigned int int_20;
unsigned int top_of_memory;
};
char far *CarvedPtr;
unsigned long int total_mem; /* total memory in system */
unsigned long int avail_mem; /* avail memory in system */
unsigned long int free_mem; /* free memory */
unsigned long biggest_free; /* largest free block now :M001 */
struct PSP_STRUC far *PSPptr;
/* skip a line */
Sub0_Message(NewLineMsg,STDOUT,Utility_Msg_Class);
/* get PSP info */
InRegs.h.ah = GET_PSP; /* get PSP function call */
intdos(&InRegs,&OutRegs);
FP_SEG(PSPptr) = OutRegs.x.bx; /* PSP segment */
FP_OFF(PSPptr) = 0; /* offset 0 */
/* Get total memory in system */
int86(MEMORY_DET,&InRegs,&OutRegs);
/* Convert to bytes */
total_mem = (unsigned long int) OutRegs.x.ax * 1024l;
avail_mem = total_mem;
/* M004 BEGIN */
/* Adjust for XBDA size */
/* XBDA size should be added to total mem size reported by INT 12 */
/* IFF XBDA is placed just at the end of conv.mem */
/* IF EMM386 or QEMM is loaded, XBDA gets relocated to EMM driver mem */
/* and int 12 reports correct size of memory in this case */
InRegs.x.bx = 0;
InRegs.x.ax = 0xc100;
int86x(0x15, &InRegs, &OutRegs, &SegRegs);
if (OutRegs.x.cflag == 0)
{
if (total_mem == ((unsigned long)SegRegs.es) * 16ul) {
FP_SEG(CarvedPtr) = SegRegs.es;
FP_OFF(CarvedPtr) = 0;
total_mem = total_mem + ( (unsigned long int) (*CarvedPtr) * 1024l) ; /* ;an002; dms;adjust total for */
}
} /* RAM carve value */
/* M004 END */
Sub1_Message(TotalMemoryMsg,STDOUT,Utility_Msg_Class,&total_mem);
Sub1_Message(AvailableMemoryMsg,STDOUT,Utility_Msg_Class,&avail_mem);
/* Calculate the total memory used. PSP segment * 16. Subtract from total to
get free_mem */
free_mem = (DOS_TopOfMemory * 16l) - (FP_SEG(PSPptr)*16l); /* ;an000;ac005; */
/* Get largest free block in system :M001 */
InRegs.x.ax = 0x4800; /* M001 */
InRegs.x.bx = 0xffff; /* M001 */
intdos(&InRegs, &OutRegs); /* M001 */
biggest_free = OutRegs.x.bx * 16L; /* Size of largest block now :M001 */
/* The largest free block in the system is either the block we are
currently in or the block we have allocated. We can either be the
topmost program or be loaded in a hole or UMB. In either case, the
larger of the 2 values gives us the largest free block :M001
*/
if ( biggest_free > free_mem ) /* M001 */
free_mem = biggest_free; /* M001 */
Sub1_Message(FreeMemoryMsg,STDOUT,Utility_Msg_Class,&free_mem);
return;
} /* end of display_low_total */
/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
char *OwnerOf(ArenaPtr)
struct ARENA far *ArenaPtr;
{
char far *StringPtr;
char *o;
unsigned far *EnvironmentSegmentPtr;
unsigned PspSegment;
int i,fPrintable;
o = &OwnerName[0];
*o = NUL;
sprintf(o,UnOwned);
PspSegment = ArenaPtr -> Owner;
if (PspSegment == 0) sprintf(o,Ibmdos);
else if (PspSegment == 8) sprintf(o,Ibmbio);
else {
FP_SEG(ArenaPtr) = PspSegment-1; /* -1 'cause Arena is 16 bytes before PSP */
StringPtr = (char far *) &(ArenaPtr -> OwnerName[0]);
/* M002 BEGIN */
fPrintable = TRUE;
/* Chars below 0x20 (Space) and char 0x7f are not printable in US and
* European Code pages. The following code checks for it and does not print
* such names. - Nagara 11/20/90
*/
for (i = 0; i < 8;i++,StringPtr++) {
#ifdef DBCS
if ( ((unsigned char)*StringPtr < 0x20) | ((unsigned char)*StringPtr == 0x7f) ) {
#else
if ( (*StringPtr < 0x20) | (*StringPtr == 0x7f) ) {
#endif
/* unprintable char ? */
if (*StringPtr) fPrintable = FALSE;
break;
}
}
if (fPrintable) { /* the name is printable */
StringPtr = (char far *) &(ArenaPtr -> OwnerName[0]);
for (i = 0; i < 8;i++)
*o++ = *StringPtr++;
*o = (char) '\0';
}
/* M002 END */
}
if (UseArgvZero) GetFromArgvZero(PspSegment,EnvironmentSegmentPtr);
return(&OwnerName[0]);
}
/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
void GetFromArgvZero(PspSegment,EnvironmentSegmentPtr)
unsigned PspSegment;
unsigned far *EnvironmentSegmentPtr;
{
char far *StringPtr;
char *OutputPtr;
unsigned far *WordPtr;
OutputPtr = &OwnerName[0];
if (UseArgvZero)
{
if (PspSegment < FP_SEG(ArenaHeadPtr))
{
if (*OutputPtr == NUL) sprintf(OutputPtr,Ibmdos);
}
else {
FP_SEG(EnvironmentSegmentPtr) = PspSegment;
FP_OFF(EnvironmentSegmentPtr) = 44;
/* FP_SEG(StringPtr) = *EnvironmentSegmentPtr; */
FP_SEG(StringPtr) = FP_SEG(EnvironmentSegmentPtr);
FP_OFF(StringPtr) = 0;
while ( (*StringPtr != NUL) || (*(StringPtr+1) != NUL) ) StringPtr++;
StringPtr += 2;
WordPtr = (unsigned far *) StringPtr;
if (*WordPtr == 1)
{
StringPtr += 2;
while (*StringPtr != NUL)
*OutputPtr++ = *StringPtr++;
*OutputPtr++ = NUL;
while ( OutputPtr > &OwnerName[0] )
{ if (*OutputPtr == (char) '.') *OutputPtr = NUL;
if ( (*OutputPtr == (char) '\\') || (*OutputPtr == (char) ':') )
{ OutputPtr++;
break;
}
OutputPtr--;
}
}
}
}
strcpy(&OwnerName[0],OutputPtr);
return;
}
/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
char *TypeOf(Header)
struct ARENA far *Header;
{
char *t;
unsigned PspSegment;
unsigned far *EnvironmentSegmentPtr;
unsigned int Message_Number;
char far *Message_Buf;
unsigned int i;
t = &TypeText[0];
*t = NUL;
Message_Number = 0xff; /* ;an000; initialize number value */
if (Header -> Owner == 8) Message_Number = StackMsg;
if (Header -> Owner == 0) Message_Number = FreeMsg;
PspSegment = Header -> Owner;
if (PspSegment < FP_SEG(ArenaHeadPtr))
{
if (Message_Number == 0xff) Message_Number = BlankMsg;
}
else {
FP_SEG(EnvironmentSegmentPtr) = PspSegment;
FP_OFF(EnvironmentSegmentPtr) = 44;
if (PspSegment == FP_SEG(Header)+1)
Message_Number = ProgramMsg;
else if ( *EnvironmentSegmentPtr == FP_SEG(Header)+1 )
Message_Number = EnvironMsg;
else
Message_Number = DataMsg;
}
InRegs.x.ax = Message_Number;
InRegs.h.dh = Utility_Msg_Class;
sysgetmsg(&InRegs,&SegRegs,&OutRegs);
FP_OFF(Message_Buf) = OutRegs.x.si;
FP_SEG(Message_Buf) = SegRegs.ds;
i = 0;
while ( *Message_Buf != (char) '\x0' )
TypeText[i++] = *Message_Buf++;
TypeText[i++] = '\x0';
return(t);
}
/* M003 BEGIN */
/*----------------------------------------------------------------------*/
/* AddMem_to_PSP */
/* Entry: PSP_ADDR (to which this mem. should be added) */
/* ARENA_START_ADDR */
/* Length_of_Arena */
/* Exit: mem_table updated. */
/* returns 1 if more than MAX_CL_ENTRIES in mem_table */
/* else 0 */
/* */
/* CAVEATS: */
/* -------- */
/* 1. any system area (BIOS,SYSINIT,DOS ) code/data is listed as belonging */
/* to PSP 8. */
/* */
/* 2. We look at the UMB_HEAD in DOS DATA to determine whether an arena */
/* is in UMB or not; For the Arena at the UMB boundary, we add one */
/* para to conv. and remaining to UMB portion of that PSP */
/* */
/* 3. Any free memory is always added as a new entry in the mem_table */
/* instead of just adding the sizes to an existing FREE entry */
/* Free memory gets added to the previous free memory if they are */
/* contiguous */
/* */
/* 4. The no of programs/free arenas cannot exceed a max of (100) */
/* (defined by MAX_CLDATA_INDEX ) */
/* If the memory is fragmented and a lot of small TSRs loaded such */
/* that we exceed this limit, we TERMINATE */
/* */
/* 5. Mem occupied by this MEM are also reported as FREE mem */
/* */
/*----------------------------------------------------------------------*/
unsigned int AddMem_to_PSP(psp,start_addr,length)
unsigned int psp;
unsigned long start_addr,length;
{
unsigned int para_no,len_in_paras,CurPSP;
int i;
extern unsigned int _psp;
para_no = (unsigned int)(start_addr >> 4); /* convert to paras*/
len_in_paras = (unsigned int)(length >> 4); /* convert to paras */
CurPSP = psp;
if (psp == _psp) psp = 0; /* treat MEM's arenas as FREE */
if (!psp) {
if (LastPSP == _psp) { /* if the prev.arena was MEM */
i = noof_progs -1; /* look at the last entry */
if (mem_table[i].psp_add != psp) /* was the last entry free ?*/
i++;
else len_in_paras++; /* account for one free arena header */
}
else i = noof_progs; /* new entry for FREE mem */
}
else
for (i = 0;i < noof_progs;i++)
if (mem_table[i].psp_add == psp) break;
/* if psp is not already listed in the table, add it */
if (i == noof_progs) {
if (noof_progs == MAX_CLDATA_INDEX) {
/* use parse error message proc to display err msg */
Parse_Message(CMemFragMsg,STDERR,Utility_Msg_Class,(char far *) NULL);
return(1);
}
mem_table[i].psp_add = psp;
noof_progs++;
}
/* add the memory to the table entry */
if (para_no < UMB_Head)
mem_table[i].mem_conv += len_in_paras;
else if (para_no == UMB_Head) {
mem_table[i].mem_conv++;
mem_table[i].mem_umb = len_in_paras-1;
}
else mem_table[i].mem_umb += len_in_paras;
LastPSP = CurPSP;
return(0);
}
/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
/************************************************************************/
/* DisplayClassification */
/* Main display proc for /C switch */
/* */
/* ENTRY: none */
/* */
/* EXIT: none */
/* */
/* find out if UMB is available by going through mem_table entries */
/* (also find out MEM's size from these entries) */
/* display memory break up for conventional memory */
/* if (UMB in system) display memmory break up for UMB memory */
/* display the total free size (= total free in conv.+total_free */
/* in UMB + MEM's size ) */
/* call DispBigFree to display the largest prog. sizes in Conv.&UMB*/
/* */
/************************************************************************/
#define CONVONLY 0
#define UMBONLY 1
void DisplayClassification()
{
unsigned long tot_freemem=0L;
char ShDSizeName[12];
int i;
unsigned int cur_psp;
char fUMBAvail=0;
/* get PSP info */
InRegs.h.ah = GET_PSP; /* get PSP function call */
intdos(&InRegs,&OutRegs);
cur_psp = OutRegs.x.bx; /* psp of MEM */
for (i=0;i <noof_progs;i++) {
if (mem_table[i].mem_umb)
fUMBAvail = TRUE;
if (mem_table[i].psp_add == cur_psp) {
tot_freemem += (long)(mem_table[i].mem_conv + mem_table[i].mem_umb);
if (fUMBAvail) break;
}
}
tot_freemem *=16l; /* convert to bytes */
Sub0_Message(CTtlConvMsg,STDOUT,Utility_Msg_Class);
Sub0_Message(NewLineMsg,STDOUT,Utility_Msg_Class);
tot_freemem += DispMemClass(CONVONLY);
Sub0_Message(NewLineMsg,STDOUT,Utility_Msg_Class);
if (fUMBAvail) {
Sub0_Message(CTtlUMBMsg,STDOUT,Utility_Msg_Class);
Sub0_Message(NewLineMsg,STDOUT,Utility_Msg_Class);
tot_freemem += DispMemClass(UMBONLY);
Sub0_Message(NewLineMsg,STDOUT,Utility_Msg_Class);
}
sprintf(ShDSizeName," (%5.1fK)",((float)tot_freemem)/1024l );
i = (fUMBAvail) ? CSumm1Msg:CSumm1AMsg;
SubC2_Message(i,STDOUT,&tot_freemem, ShDSizeName);
DispBigFree(fUMBAvail,cur_psp);
}
/************************************************************************/
/* DispMemClass */
/* (displays the progs and FREE sizes in either the */
/* conventional or UMB) */
/* */
/* ENTRY: memtype => Conventional(0) /UMB (1) */
/* */
/* EXIT: total_freemem_size (in bytes) */
/* */
/* go through mem_table entries and display NON-ZERO size, NON-FREE */
/* entries in the given mem_type */
/* go through mem_table entries and display NON_ZERO size, FREE */
/* entries in the given mem_type */
/* calculate the total free mem size in the given mem type &return */
/* */
/* CAVEATS: */
/* Arenas marked as belonging to MSDOS (code) in UMB are displayed */
/* as SYSTEM */
/* */
/************************************************************************/
unsigned long DispMemClass(memtype)
int memtype;
{
int i,msgtype;
unsigned int cur_memsize;
unsigned long memsize;
char *nameptr;
char ShDSizeName[12];
unsigned long tot_free = 0;
struct ARENA far *ArenaPtr;
Sub0_Message(CTtlNameMsg,STDOUT,Utility_Msg_Class);
Sub0_Message(CTtlUScoreMsg,STDOUT,Utility_Msg_Class);
for (i=0; i <noof_progs; i++) {
cur_memsize = (memtype == CONVONLY) ? mem_table[i].mem_conv:mem_table[i].mem_umb;
if (!cur_memsize) continue;
if (!mem_table[i].psp_add) continue;
msgtype = 0;
if (mem_table[i].psp_add == 8) /* if DOS area */
msgtype = (memtype == CONVONLY)?IbmdosMsg:SystemMsg;
if (!msgtype) {
FP_SEG(ArenaPtr) = mem_table[i].psp_add-1;
/* -1 'cause Arena is 16 bytes before PSP */
FP_OFF(ArenaPtr) = 0;
nameptr = OwnerOf(ArenaPtr);
}
else nameptr = NULL;
memsize = ((long) cur_memsize) *16l;
sprintf(ShDSizeName," (%5.1fK)",((float)memsize)/1024l );
SubC4_Message(MainLineMsg,STDOUT,nameptr,msgtype,&memsize, ShDSizeName);
}
for (i=0; i <noof_progs; i++) {
if (mem_table[i].psp_add) continue;
cur_memsize = (memtype == CONVONLY) ? mem_table[i].mem_conv:mem_table[i].mem_umb;
if (!cur_memsize) continue;
tot_free += (long) cur_memsize;
memsize = ((long) cur_memsize) *16l;
sprintf(ShDSizeName," (%5.1fK)",((float)memsize)/1024l );
SubC4_Message(MainLineMsg,STDOUT,NULL,CFreeMsg,&memsize, ShDSizeName);
}
tot_free *= 16l;
sprintf(ShDSizeName," (%5.1fK)",((float)tot_free )/1024l );
Sub0_Message(NewLineMsg,STDOUT,Utility_Msg_Class);
SubC2_Message(CTotalFreeMsg,STDOUT,&tot_free, ShDSizeName);
return(tot_free);
}
/************************************************************************/
/* DispBigFree */
/* ENTRY: UMBAvailable? (flag) 1-> there is UMB */
/* MEM's PSP */
/* EXIT: none (largest prog.sizes displayed) */
/* This finds out and displays the largest contig.mem available in */
/* in Conventional and UMB memory */
/* This calculation is done assuming that MEM is not loaded */
/* */
/************************************************************************/
void DispBigFree(fUMBAvail,cur_psp)
char fUMBAvail;
unsigned int cur_psp;
{
int i;
unsigned int ConvBigFree = 0;
unsigned int UMBBigFree = 0;
unsigned long TmpBigFree;
char ShDSizeName[12];
unsigned far *Env_ptr;
unsigned int env_mem,BigFree;
char fMEMHigh;
/* assume that the biggest free size is the top of mem we got when */
/* MEM was loaded */
FP_SEG(Env_ptr) = cur_psp;
FP_OFF(Env_ptr) = 44; /* get the env for MEM */
FP_SEG(Env_ptr) = (*Env_ptr)-1; /* get to arena for env. */
FP_OFF(Env_ptr) = 3; /* get the size of environment */
env_mem = *Env_ptr + 1; /* 1 extra para for arena header */
fMEMHigh = (char)((cur_psp > UMB_Head) ? 1:0);
BigFree = DOS_TopOfMemory - cur_psp;
if (fMEMHigh ) /* mem was loaded higher */
UMBBigFree = BigFree;
else
ConvBigFree = BigFree;
for (i =0; i<noof_progs;i++) {
if (mem_table[i].psp_add) continue; /* skip non-FREE entries */
if (mem_table[i].mem_conv > ConvBigFree)
ConvBigFree = mem_table[i].mem_conv;
if (mem_table[i].mem_umb > UMBBigFree)
UMBBigFree = mem_table[i].mem_umb;
}
if (fMEMHigh) { /* MEM was loaded high */
if (FP_SEG(Env_ptr) > UMB_Head) /* env also in UMB */
if (UMBBigFree == (BigFree + env_mem))
UMBBigFree = BigFree;
}
else { /* MEM was loaded low */
if (FP_SEG(Env_ptr) < UMB_Head) /* env also in Conv */
if (ConvBigFree == (BigFree + env_mem))
ConvBigFree = BigFree;
}
TmpBigFree = ((unsigned long)ConvBigFree) * 16l;
sprintf(ShDSizeName," (%5.1fK)",((float)TmpBigFree)/1024l );
SubC2_Message(CSumm2Msg,STDOUT,&TmpBigFree, ShDSizeName);
if (fUMBAvail) {
TmpBigFree = ((unsigned long)UMBBigFree) * 16l;
sprintf(ShDSizeName," (%5.1fK)",((float)TmpBigFree)/1024l );
SubC2_Message(CSumm3Msg,STDOUT,&TmpBigFree, ShDSizeName);
}
}
/* M003 END */