Click here to Skip to main content
15,888,351 members
Articles / Desktop Programming / MFC
Article

System Information

Rate me:
Please Sign up or sign in to vote.
4.58/5 (55 votes)
19 Aug 20032 min read 471.5K   17.9K   154   131
Obtaining Information from Computer Hardware/Software

Screen shot of program

Introduction

This program shows you a very simple way to determine your PC hardware and software. It queries operating system for the following Hardware/Software:

  • Operating System Version (Thanks to PJ Naughter)
  • Computer Name
  • IP Address of Computer
  • User Name
  • Internet Explorer Version
  • Total RAM
  • Free Memory
  • Number of Hard Disk Drives
  • Hard Disk Total Space/Free Space/Used Space
  • CDROM Drives
  • Monitor Resolution
  • Color Depth
  • Number of CPUs (Thanks to Iain Chesworth)
  • CPU Speed
  • CPU Identifier
  • CPU Vendor Identifier
  • Operating System Folder
  • System Folder

Program structure

By clicking the combo box and changing it's item, selected item is determined and it's ID passed to Process member function of dialog. The Process member function takes ID of query and returns the proper result. Body of Process has a lot of code to prepares result and if any error has occurred, the error string will be returned.

How to use

Add the following header and implementation files to your project:
  • cup_info.h, cpu_info.cpp: For CPU Information like Speed, ID, Vendor ID,...
  • dtwinver.h, dtwinver.cpp: For Operating System Version (e.g. Build Number and Service Packs)
  • SysInfoDefs.h, SysInfoDefs.cpp: For General System Information like Total RAM, Number of Hard Disk Drives, Disk Space/Free Space/Used Space
  • SmartDef.h: For IDE S.M.A.R.T. commands to query from IDE hard disks that support SMART.

Functions

Below table shows all functions that are used to determine Hardware/Software of the computer.

CString DetermineIEVer();Determining Internet Explorer Version (Build Number)
CString QueryHardDisks();Calculating Number of Hard Disks and Number of Cylinders, Tracks per Cylinders, Sectors per Tracks, Bytes per Sector and Total Capacity for each Hard Disks
CString QueryDriveSpace();Calculating Drive Space/Free Space/Used Space of All Hard Drives
CString QueryCDDrive();Determining Number of CD Drives
CString QueryTotalRAM()Calculating Total Physical RAM (Random Access Memory)
CString QueryFreeRAM();Calculating Free Physical Memory
CString QueryUserName()User Name of current user
CString QueryComputerName();Computer Name
CString QueryCPUInfo();Number of CPU Installed on Mother Board
CString QueryCPUSpeed();Speed of each CPU
CString QueryCPUID();ID of each CPU
CString QueryCPUVendorID();ID of CPU Vendor
CString QueryResolution();Calculating Monitor Resolution in Pixel
CString QueryPixelDepth();Calculating Color Depth of any Pixel
CString QueryOS();Determining Operating System Version (Build Number) and it's Service Pack
CString QueryLocalIPAddress();Determining IP Address of Computer
CString QueryHDDSmartCommand();Query IDE hard disks that support SMART (Self-Monitoring Analysis & Reporting Technology).
CString QueryDirectory(char* sFolder,int iFolder);Determining Full Path of Specified Folder where sFolder is Folder Name and iFolder is Folder Shell ID Number
CString GetCommandError();Determining last occurred error

Requirements

  • Latest Platform SDK
  • Visual Studio 6.0 with service pack 5

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
CEO Solaris Electronics LLC
United Arab Emirates United Arab Emirates
I was born in Shiraz, a very beautiful famous city in Iran. I started programming when I was 12 years old with GWBASIC. Since now, I worked with various programming languages from Basic, Foxpro, C/C++, Visual Basic, Pascal to MATLAB and now Visual C++.
I graduated from Iran University of Science & Technology in Communication Eng., and now work as a system programmer for a telecommunication industry.
I wrote several programs and drivers for Synthesizers, Power Amplifiers, GPIB, GPS devices, Radio cards, Data Acquisition cards and so many related devices.
I'm author of several books like Learning C (primary and advanced), Learning Visual Basic, API application for VB, Teach Yourself Object Oriented Programming (OOP) and etc.
I'm winner of January, May, August 2003 and April 2005 best article of month competition, my articles are:


You can see list of my articles, by clicking here


Comments and Discussions

 
GeneralSmall mistake for Total memory Pin
cpsworld11-Jan-06 7:08
cpsworld11-Jan-06 7:08 
GeneralRe: Small mistake for Total memory Pin
Abbas_Riazi12-Jan-06 0:10
professionalAbbas_Riazi12-Jan-06 0:10 
GeneralHarddisk and drive name Pin
ugur_basak23-Nov-05 20:56
ugur_basak23-Nov-05 20:56 
GeneralRe: Harddisk and drive name Pin
ugur_basak23-Nov-05 21:57
ugur_basak23-Nov-05 21:57 
GeneralMemory Leak detected Pin
Juri Barthel24-Jun-05 1:05
Juri Barthel24-Jun-05 1:05 
GeneralRe: Memory Leak detected Pin
Abbas_Riazi24-Jun-05 1:13
professionalAbbas_Riazi24-Jun-05 1:13 
GeneralMore features Pin
Hachaso30-May-05 1:09
Hachaso30-May-05 1:09 
GeneralStructure misalignment Pin
smedlytonker21-Feb-05 9:06
smedlytonker21-Feb-05 9:06 
You need to add the pack paragma to your code. I noticed that the data in your structures was misaligned when I was modifying your code to retrieve the temperature of the hard drive.

#pragma pack(1)
//---------------------------------------------------------------------
// The following structure defines the structure of a Drive Attribute
//---------------------------------------------------------------------
typedef struct _DRIVEATTRIBUTE {
BYTE bAttrID; // Identifies which attribute
WORD wStatusFlags; // see bit definitions below
BYTE bAttrValue; // Current normalized value
BYTE bWorstValue; // How bad has it ever been?
BYTE bRawValue[6]; // Un-normalized value
BYTE bReserved; // ...
} DRIVEATTRIBUTE, *PDRIVEATTRIBUTE, *LPDRIVEATTRIBUTE;

//---------------------------------------------------------------------
// The following structure defines the structure of a Warranty Threshold
// Obsoleted in ATA4!
//---------------------------------------------------------------------
typedef struct _ATTRTHRESHOLD {
BYTE bAttrID; // Identifies which attribute
BYTE bWarrantyThreshold; // Triggering value
BYTE bReserved[10]; // ...
} ATTRTHRESHOLD, *PATTRTHRESHOLD, *LPATTRTHRESHOLD;

//---------------------------------------------------------------------
// The following struct defines the interesting part of the IDENTIFY
// buffer:
//---------------------------------------------------------------------
typedef struct _IDSECTOR {
USHORT wGenConfig;
USHORT wNumCyls;
USHORT wReserved;
USHORT wNumHeads;
USHORT wBytesPerTrack;
USHORT wBytesPerSector;
USHORT wSectorsPerTrack;
USHORT wVendorUnique[3];
CHAR sSerialNumber[20];
USHORT wBufferType;
USHORT wBufferSize;
USHORT wECCSize;
CHAR sFirmwareRev[8];
CHAR sModelNumber[40];
USHORT wMoreVendorUnique;
USHORT wDoubleWordIO;
USHORT wCapabilities;
USHORT wReserved1;
USHORT wPIOTiming;
USHORT wDMATiming;
USHORT wBS;
USHORT wNumCurrentCyls;
USHORT wNumCurrentHeads;
USHORT wNumCurrentSectorsPerTrack;
ULONG ulCurrentSectorCapacity;
USHORT wMultSectorStuff;
ULONG ulTotalAddressableSectors;
USHORT wSingleWordDMA;
USHORT wMultiWordDMA;
BYTE bReserved[128];
} IDSECTOR, *PIDSECTOR;

#pragma pack()


*** The following might be useful updates too:
ULONGLONG PrintSmartAttribRawValue(PCHAR szOut, PDRIVEATTRIBUTE attribute)
{
ULONGLONG rawvalue;
BYTE word[3];
int j;

// convert the six individual bytes to a long long (8 byte) integer.
// This is the value that we'll eventually return.
rawvalue = 0;
for (j = 0; j < 6; j++)
{
// This looks a bit roundabout, but is necessary. Don't
// succumb to the temptation to use raw[j]<<(8*j) since under
// the normal rules this will be promoted to the native type.
// On a 32 bit machine this might then overflow.
ULONGLONG temp;
temp = attribute->bRawValue[j];
temp <<= 8*j;
rawvalue |= temp;
}

// convert quantities to three two-byte words
for(j = 0; j < 3; j++)
{
word[j] = attribute->bRawValue[2*j+1];
word[j] <<= 8;
word[j] |= attribute->bRawValue[2*j];
}

// This switch statement is where we handle Raw attributes
// that are stored in an unusual vendor-specific format,
switch (attribute->bAttrID)
{
// Spin-up time
case 3:
szOut += sprintf(szOut, "%d", word[0]);
// if second nonzero then it stores the average spin-up time
if(word[1])
szOut += sprintf(szOut, " (Average %d)", word[1]);
break;

// Power on time
case 9:
szOut += sprintf(szOut, "%I64u", rawvalue); //stored in hours
break;

// Load unload cycles
case 193:
szOut += sprintf(szOut, "%I64u", rawvalue);
break;
// Temperature
case 194:
szOut += sprintf(szOut, "%d", word[0]);
if (!(rawvalue==word[0]))
{
int min = word[1] < word[2]? word[1]: word[2];
int max = word[1] > word[2]? word[1]: word[2];
// The other bytes are in use. Try IBM's model
szOut += sprintf(szOut, " (Lifetime Min/Max %d/%d)", min, max);
}
break;

default:
szOut += sprintf(szOut, "%I64u", rawvalue);
break;
}

// Return the full value
return rawvalue;
}


// Note some attribute names appear redundant because different
// manufacturers use different attribute IDs for an attribute with the
// same name. The variable val should contain a non-zero value if a particular
// attributes has a non-default interpretation.
PCHAR GetSmartAttribName(BYTE id)
{
PCHAR szName = "Unknown_Attribute";

switch(id)
{
case 1: szName = "Raw Read Error Rate"; break;
case 2: szName = "Throughput Performance"; break;
case 3: szName = "Spin Up Time"; break;
case 4: szName = "Start Stop Count"; break;
case 5: szName = "Reallocated Sector Ct"; break;
case 6: szName = "Read Channel Margin"; break;
case 7: szName = "Seek Error Rate"; break;
case 8: szName = "Seek Time Performance"; break;
case 9: szName = "Power On Hours"; break;
case 10: szName = "Spin Retry Count"; break;
case 11: szName = "Calibration Retry Count"; break;
case 12: szName = "Power Cycle Count"; break;
case 13: szName = "Read Soft Error Rate"; break;
case 191: szName = "G-Sense Error Rate"; break;
case 192: szName = "Power-Off Retract Count"; break;
case 193: szName = "Load Cycle Count"; break;
case 194: szName = "Temperature Celsius"; break;
case 195: szName = "Hardware ECC Recovered"; break;
case 196: szName = "Reallocated Event Count"; break;
case 197: szName = "Current Pending Sector"; break;
case 198: szName = "Offline Uncorrectable"; break;
case 199: szName = "UDMA CRC Error Count"; break;
case 200: szName = "Write Error Count"; break;
case 201: szName = "Detected TA Count"; break;
case 202: szName = "TA Increase Count"; break;
case 203: szName = "Run Out Cancel"; break;
case 204: szName = "Shock Count Write Opern"; break;
case 205: szName = "Shock Rate Write Opern"; break;
case 206: szName = "Flying Height"; break;
case 207: szName = "Spin High Current"; break;
case 208: szName = "Spin Buzz"; break;
case 209: szName = "Offline Seek Performnce"; break;
case 220: szName = "Disk Shift"; break;
case 221: szName = "G-Sense Error Rate"; break;
case 222: szName = "Loaded Hours"; break;
case 223: szName = "Load Retry Count"; break;
case 224: szName = "Load Friction"; break;
case 225: szName = "Load Cycle Count"; break;
case 226: szName = "Load-in Time"; break;
case 227: szName = "Torq-amp Count"; break;
case 228: szName = "Power-off Retract Count"; break;
case 230: szName = "Head Amplitude"; break;
case 231: szName = "Temperature Celsius"; break;
case 240: szName = "Head Flying Hours"; break;
case 250: szName = "Read Error Retry Rate"; break;
default: szName = "Unknown Attribute"; break;
}

return szName;
}

/****************************************************************************
*
* DoPrintData
*
* FUNCTION: Display the SMART Attributes and Thresholds
*
****************************************************************************/
CString DoPrintData(PCHAR pAttrBuffer, PCHAR pThrsBuffer, BYTE bDriveNum)
{
int i;
PDRIVEATTRIBUTE pDA;
PATTRTHRESHOLD pAT;
BYTE Attr;
CString Result;

//
// Print the drive number
//
char Temp[512]="";
sprintf(Temp,"\r\nData for Drive Number %d\n", bDriveNum);
Result+=Temp;
//
// Print the revisions of the data structures
//
sprintf(Temp, "Attribute Structure Revision Threshold Structure Revision\r\n");
Result+=Temp;

sprintf(Temp," %d %d\r\n\r\n",
(WORD)pAttrBuffer[0],
(WORD)pThrsBuffer[0]);

Result+=Temp;
//
// Print the header and loop through the structures, printing
// the structures when the attribute ID is known.
//
sprintf(Temp, " -Attribute Name- -Attribute Value- -Threshold Value- -Raw Value-\r\n");
Result+=Temp;

pDA = (PDRIVEATTRIBUTE)&pAttrBuffer[2];
pAT = (PATTRTHRESHOLD)&pThrsBuffer[2];

for (i = 0; i < NUM_ATTRIBUTE_STRUCTS; i++)
{
Attr = pDA->bAttrID;

char szOut[64] = {0};
PrintSmartAttribRawValue(szOut, pDA);

if (Attr)
{
sprintf(Temp,"%2X %-29s%d%20c%d %s\r\n",
pDA->bAttrID,
GetSmartAttribName(pDA->bAttrID),
pDA->bAttrValue,
' ',
pAT->bWarrantyThreshold, szOut);

Result+=Temp;
}
pDA++;
pAT++;
}

return Result;
}
Generallots of compile errors Pin
polunga25-Jan-05 19:06
polunga25-Jan-05 19:06 
GeneralRe: lots of compile errors Pin
Abbas_Riazi25-Jan-05 19:48
professionalAbbas_Riazi25-Jan-05 19:48 
Generalwindows xp Pin
strugglingCoder6-Jan-05 18:50
strugglingCoder6-Jan-05 18:50 
GeneralRe: windows xp Pin
Abbas_Riazi6-Jan-05 20:10
professionalAbbas_Riazi6-Jan-05 20:10 
GeneralRe: windows xp Pin
strugglingCoder11-Jan-05 10:30
strugglingCoder11-Jan-05 10:30 
GeneralRe: windows xp Pin
Abbas_Riazi11-Jan-05 19:01
professionalAbbas_Riazi11-Jan-05 19:01 
QuestionHow to get centrino cpu speed correctly? Pin
Member 223907119-Oct-04 11:36
Member 223907119-Oct-04 11:36 
AnswerRe: How to get centrino cpu speed correctly? Pin
Ing-Long Eric Kuo6-Dec-04 23:44
Ing-Long Eric Kuo6-Dec-04 23:44 
GeneralSlight error and missing SMART infos Pin
Raul Sobon12-Oct-04 15:26
Raul Sobon12-Oct-04 15:26 
GeneralRe: Slight error and missing SMART infos Pin
Abbas_Riazi12-Oct-04 21:06
professionalAbbas_Riazi12-Oct-04 21:06 
GeneralRe: Slight error and missing SMART infos Pin
Orkblutt28-Sep-05 18:09
Orkblutt28-Sep-05 18:09 
GeneralRe: Slight error and missing SMART infos Pin
Abbas_Riazi28-Sep-05 19:59
professionalAbbas_Riazi28-Sep-05 19:59 
GeneralRe: Slight error and missing SMART infos Pin
Orkblutt29-Sep-05 2:12
Orkblutt29-Sep-05 2:12 
GeneralRe: Slight error and missing SMART infos Pin
Abbas_Riazi29-Sep-05 2:22
professionalAbbas_Riazi29-Sep-05 2:22 
GeneralCentrino Unsupported Pin
Guoshima23-Aug-04 23:40
Guoshima23-Aug-04 23:40 
GeneralMATLAB &amp; C++ or JAVA Pin
ama200019-Aug-04 7:49
ama200019-Aug-04 7:49 
GeneralMissing comma Pin
Dimitris Vasiliadis9-Aug-04 22:51
Dimitris Vasiliadis9-Aug-04 22:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.