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

📄 meminfo.c

📁 Dos6.0
💻 C
📖 第 1 页 / 共 5 页
字号:
/*********************************************************************
 * Microsoft Diagnostics Version 2.0
 *
 * A diagnostic utility to detect as much useful information about a
 *   customer's computer system as is possible.
 *
 * Microsoft Diagnostics:  We detect the World.
 *
 * MEMINFO.C - Source file for obtaining memory information.
 ********************************************************************/


/* Include Files */

#include "msd.h"


/*********************************************************************
 * GetMemInfo - Gets the memory information.
 *
 * pMem         - Pointer to memory information structure.
 * fMinimumInfo - TRUE if minimum info is requested.
 *
 * Returns:  TRUE if an error occured.
 *********************************************************************/

BOOL GetMemInfo (MEMORY_STRUCT *pMem, BOOL fMinimumInfo)
{
  BOOL fReturnValue = FALSE;  /* Return value from various GetInfo calls */
  WORD wSize;                 /* Size, in bytes, to store the data       */
  COMPUTER_STRUCT *pComputer = NULL;  /* Computer info structure pointer */
  WORD wProcessor;            /* Stores the processor type               */
  WORD wBusType;              /* Stores the computer's bus type          */


  wSize = GetInfoSize (IDI_COMPUTER_RECORD, FALSE);

  if (wSize == 0)
    return (TRUE);

  pComputer = malloc (wSize);

  if (pComputer == NULL)
    {
      OutOfMemory();
      return (TRUE);
    }

  /* Zero out the structure */
  memset (pComputer, '\0', wSize);

  fReturnValue = GetComputerIrqInfo (pComputer);
  if (fReturnValue)
    {
      free (pComputer);
      return (fReturnValue);
    }

  wProcessor = pComputer->wProcessor;
  wBusType   = pComputer->wBusType;
  free (pComputer);


  /* Initialize the memory info structures */
  MInitialize ((MEMORY_STRUCT FAR *) pMem);

  /* Get conventional memory size */
  Get_Conv_Mem_Info ((MEMORY_STRUCT FAR *) pMem);

  if (wProcessor >= _80286)
    {
      /* Get installed extended according to CMOS */
      GetCMOSExtended ((MEMORY_STRUCT FAR *) pMem);

      /* Get non-XMS extended memory size */
      Get_Ext_Mem_Info ((MEMORY_STRUCT FAR *) pMem);

      /* Get XMS extended memory info */
      Get_Xmm_Info ((MEMORY_STRUCT FAR *) pMem, wProcessor);

      /* Make sure we're on at least a 386 for DPMI information */
      if (wProcessor != _80286)
        GetDPMIInfo ((MEMORY_STRUCT FAR *) pMem);
    }

  /* Check for an EMM driver */
  Test_For_Emm ((MEMORY_STRUCT FAR *) pMem);

  if (pMem->iEmm_Is_There)
    {
      /* Get expanded memory info */
      Get_Emm_Info ((MEMORY_STRUCT FAR *) pMem);

      /* If on a 386 or greater */
      if (/* !(pMem->iDPMIPresent) && */ wProcessor >= _80386)
        {
          /* check for and get VCPI info */
          GetVCPIInfo ((MEMORY_STRUCT FAR *) pMem);
        }
    }

  if (fMinimumInfo)
    return (FALSE);

  /* Get the visual memory map */
  Get_VisualMemMap ((MEMORY_STRUCT FAR *) pMem, wBusType);

  /* Fill the visual memory map overlay with EMS page frame and UMBs */
  VisualMapOverlay ((MEMORY_STRUCT FAR *) pMem);

  return (FALSE);
}


/************************************************************************
*
* Function MInitialize()
*
* This function initializes fields in the Mem_Info_St structure to
* zero values.
*
************************************************************************/

int MInitialize (MEMORY_STRUCT FAR * pMem_Info)

{
  /* Initialize the fields in the Mem_Info_St structure */
  _fmemset (pMem_Info, '\0', sizeof (MEMORY_STRUCT));

  return (0);
}

/***************************************************************************
*
* Function Get_Conv_Mem_Info()
*
* This function gets the amount of conventional memory in bytes and the
* amount of free conventional memory in bytes. It uses a call to BIOS
* function Int 12H.                                                                    *
*
*
* Mem_Info_St Fields Set
* ----------------------
*
* lConv_Mem     = The amount of conventional memory in bytes
* lFree_Conv_Mem  = The amount of free conventional memory in bytes
*
*
* Local Variables Used                                      
    *
* --------------------
*
*
* inregs, outregs : Used for reading and writing the general purpose
*         registers.
* segment_prefix  : Used to hold the segment address of the program
*         segment prefix.
*
***************************************************************************/

int Get_Conv_Mem_Info (MEMORY_STRUCT FAR * pMem_Info)

{
  union REGS inregs, outregs;
  long segment_prefix;

  int86(0x12, &inregs, &outregs);

  pMem_Info->lConv_Mem = outregs.x.ax * 1024L;

  segment_prefix = 0L;
  segment_prefix = segment_prefix + ((long)(_psp) * 0x10);

  pMem_Info->lFree_Conv_Mem = pMem_Info->lConv_Mem - segment_prefix;

  return (0);
}

/***************************************************************************
*
* Function Get_Ext_Mem_Info()
*
* This function gets the amount of extended memory in bytes. It uses a
* call to BIOS function Int 15H, subfunction 88H.
*
*
* Mem_Info_St Fields Set
* ----------------------
*
* lExt_Mem      = The amount of extended memory in bytes
*
*
* Local Variables Used
* --------------------
*
* inregs, outregs : Used for reading and writing the general purpose
*         registers.
*
***************************************************************************/

int Get_Ext_Mem_Info (MEMORY_STRUCT FAR * pMem_Info)

{
  union REGS inregs, outregs;
  static int iFirstTime = 1;


  /* Check to see if this is the first time this routine was called.
     We do this because of the XMS memory routine which is called
     after this. In the XMS memory routine, if an XMS driver is found,
     the driver hooks into INT 15 calls. Subsequent calls to INT 15
     to get the amount of extended memory then return 0K. By calling
     this routine first and then never checking it again, we are able
     to get a valid value for extended memory at least the first time
     we are run on the machine */

  if (iFirstTime)
  {
    inregs.h.ah = 0x88;
    int86(0x15, &inregs, &outregs);

    pMem_Info->iExt_Mem = outregs.x.ax;

    iFirstTime = 0;
  }

  return (0);
}

/***************************************************************************
*
* Function GetCMOSExtended ()
*
* This function gets the amount of installed extended memory according to
* the CMOS.
*
***************************************************************************/

int GetCMOSExtended (MEMORY_STRUCT FAR * pMem_Info)

{
  int iHighByte, iLowByte, iTotalMemory;
  int iLoop;

  outp (0x70, 0x17);

  for (iLoop = 0; iLoop < 100; iLoop++)
    ;

  iLowByte = inp (0x71);


  outp (0x70, 0x18);

  for (iLoop = 0; iLoop < 100; iLoop++)
    ;

  iHighByte = inp (0x71);


  iTotalMemory = (iHighByte << 8) + iLowByte;

  pMem_Info->iCMOSExtended = iTotalMemory;

  return (0);
}

/***************************************************************************
*
* Function Test_For_Emm()
*
* This function tests for the existence of an EMM driver. It makes a call
* to Int 21H Function 35H to get the address of the interrupt handler for
* the EMM driver.  It then looks at offset 0AH of the device header to
* check for the guaranteed name of the EMM driver, EMMXXXX0. If the
* guaranteed name is found, there is an EMM driver installed and the value
* True is put in the iEmm_Is_There field of the Mem_Info_St structure.
* If the guaranteed name is not found, a value of False is put in the
* iEmm_Is_There field of the Mem_Info_St structure.
*
*
* Mem_Info_St Fields Set
* ----------------------
*
* iEmm_IS_There  = 1 if an EMM driver is found, 0 if not
*
*
* Local Variables Used
* --------------------
*
* inregs, outregs:  For loading and reading the general purpose regs.
* segments     :  For loading and reading the segment regs.
* addr_of_emm  :  The base address of the EMM driver, if it is there.
* ptr_to_emm   :  A pointer to the base address of the EMM driver
* name_field   :  An array to hold the string found at the name field of
*         device header of the EMM driver.
* test_name    :  An array to hold the guaranteed name of the EMM
*         driver, EMMXXXX0.
* index      :  Used for loop control.
* True, False  :  Used for Boolean testing.
*
***************************************************************************/

int Test_For_Emm (MEMORY_STRUCT FAR * pMem_Info)

{
  union REGS inregs, outregs;
  struct SREGS segments;
  unsigned long addr_of_emm;
  char far *ptr_to_emm = NULL;
  char name_field[9];
  char test_name[9] = {
        'E', 'M', 'M', 'X',
        'X', 'X', 'X', '0', '\0'
  };
  int index;
  int True = 1;
  int False = 0;

  /* load AL with the EMM int vector of 67H and prepare
     to call Int 21H, Function 35H */

  inregs.h.al = 0x67;
  inregs.h.ah = 0x35;

  /* After this call, the ES reg will contain the EMM handler address
     if it is there */

  int86x(0x21, &inregs, &outregs, &segments);
  segread(&segments);

  addr_of_emm = 0L;

  /* Load addr_of_emm with address in the ES reg, then shift it left
     16 bits to get it into the high order word */

  addr_of_emm = (addr_of_emm | segments.es) <<16;

  /* Add the offset of 0AH to make ptr_to_emm point to the name field
     in the device header of the EMM driver */

  ptr_to_emm = (unsigned char far *)addr_of_emm + 0x0A;

  /* Load the the first 8 characters beginning at the address pointed
     to by the pointer ptr_to_emm, then add a terminating \0 */

  for(index = 0; index < 8; ++index)
  {
    name_field[index] = *ptr_to_emm;
         ++ptr_to_emm;
  }
  name_field[index] = '\0';

  /* Compare the characters loaded into name_field[] against the
     guaranteed EMM driver name stored in test_name[]. Set
     iEmm_Is_There to True if equal, False if not */

  if (strcmp(test_name, name_field))
    pMem_Info->iEmm_Is_There = False;
  else
    pMem_Info->iEmm_Is_There = True;

  return (0);
}

/**************************************************************************
*
* Function Get_Emm_Info()
*
* This function gets the EMM driver version, the total number of 16K EMM
* pages and the number of 16K EM pages currently available.
*
*
* Mem_Info_St Fields Set
* ----------------------
*
* iEmm_VersionMajor = The EMS version supported by the EMS driver
* iEmm_VersionMinor = The EMS version supported by the EMS driver
* iTotal_Emm_Pages  = The total number of logical expanded memory pages
*                     present
* iFree_Emm_Pages   = The number of logical pages not allocated
* iEmm_Ver_Err      = Error code returned while getting the version
* iEmm_Size_Err     = Error code returned while getting allocation info
*
*
* Local Variables Used
* --------------------
*
* inregs, outregs  : Used to load and read the general purpose
*            registers
* int_portion    : Used to figure the integer portion of the version
* frac_portion     : Used to figure the fractional portion of the
*            version
* uiPageFrameAddress : Used to get the EMS page frame address
* uiMappablePages  : Used to get the number of LIM 4.0 mappable pages
*
**************************************************************************/

int Get_Emm_Info(MEMORY_STRUCT FAR * pMem_Info)

{
  union REGS inregs, outregs;
  struct SREGS segments;
  int int_portion, frac_portion;
  unsigned int uiPageFrameAddress;
  unsigned int *pPtrToConfigBuffer = NULL;


  /* Get the EMM version */

  inregs.h.ah = 0x46;
  int86(0x67, &inregs, &outregs);

  if (outregs.h.ah == 0x0)

⌨️ 快捷键说明

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