Category : OS/2 Files
Archive   : SYSINFO.ZIP
Filename : SYSINFO.C

 
Output of file : SYSINFO.C contained in archive : SYSINFO.ZIP
/*----------------------------------
SysInfo.c - summary of system statistics

Largest free memory block, updated every .75 seconds
Displays Free CPU cycles, updated every .75 seconds
Time of day, updated every .75 seconds
swap file size, updated every 3 seconds
free disk space on 1 drv, updated every 3 seconds

Automatically positions itself at the top of the screen in a box 2.5
system characters high. Double clicking anywhere in the client window
will cause the the frame controls to be hidden, or restored if already
hidden. Keyboard accelerators will still work while the frame is hidden.

Program can also be minimized.

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

#define INCL_WIN
#define INCL_GPI
#define INCL_DOS

#include
#include
#include
#include
#include
#include
#include

#define ID_TIMER 1
#define MAX_CHILDREN 10
#define CH_MEMTEXT 1
#define CH_MEMVAL 0
#define CH_SWAPTEXT 3

#define CH_SWAPVAL 2
#define CH_CLOCKTEXT 5
#define CH_CLOCKVAL 4
#define CH_CPUTEXT 7
#define CH_CPUVAL 6
#define CH_DISKTEXT 9
#define CH_DISKVAL 8

#define SWAPFILE "c:\\os2\\system\\swapper.dat"

MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
MRESULT EXPENTRY ChildProc (HWND, USHORT, MPARAM, MPARAM) ;
VOID SizeTheWindow( HWND );
void SwitchList( HWND hwndFrame, HPOINTER hptrIcon );
void far cdecl CountCyc( PVOID nl );
void GetFontInfo(HWND hwnd, PUSHORT cyChar, PUSHORT cxChar, PUSHORT cyDesc);
int ComputeFree(short DriveNum, float *fAvail );
SHORT CreateChildren( HWND hwndParent );
VOID ToggleFrameControls( HWND hwndFrame );
VOID UpdateLong( PHWND ahwndChild );
VOID UpdateShort( PHWND ahwndChild );

// window handles for hiding frame controls and creating children
HWND hwndFrame, hwndSys, hwndMin, hwndTitle;
HWND hwndChild[ MAX_CHILDREN ];
SHORT fHidden = 0;

// font info for sizing windows
SHORT cyChar, cxChar, cyDesc;

// raw data from CPU cycles count
ULONG uCalibVal = 0, uCurVal = 0, ulLast = 1;

// params for free disk space
USHORT usDriveNum = 3, fIsRed;
float fFreeSpace = 0.0;

// size of the swap file
ULONG ulSwapSize = 0;

// largest free block
ULONG ulFrSize = 0;


/*
Function: main

Description:
Entry point for system info program. Creates the client window and
starts the thread for the CPU monitor. Takes two command line params.
First param is the drive letter. If not present it defaults to C. This
is the drive on which the free space will be monitored.

If a second param is present and equal to /cal, the cpu counter will
be recalibrated. This should be done with no other programs running
to get a better idea of a true idle system.

Values Returned:
None.

Notes:

*/

int main ( int argc, char **argv )

{
static PSZ pszClientClass = "System Info" ;
static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_ICON |
FCF_MINBUTTON | FCF_BORDER;
CHAR achBuf[12];
HPOINTER hwndIcon; /* handle to our programs icon */
HAB hab;
HMQ hmq;
HWND hwndClient;
QMSG qmsg;

usDriveNum = 3;

PrfQueryProfileString( HINI_USERPROFILE, "System Info",
"Calibration Value", "0", achBuf, 12L );
uCalibVal = atol( achBuf );

if ( argc >= 2 )
usDriveNum = toupper( *argv[1] ) - 'A' + 1; // pick up a drive letter.
if ( argc == 3 && !stricmp( argv[2], "/cal" ) )
uCalibVal = 0; // mark for recal

_beginthread( CountCyc, NULL, 8000, NULL );

hab = WinInitialize( 0 );
hmq = WinCreateMsgQueue( hab, 0 );

WinRegisterClass(hab, pszClientClass, ClientWndProc, CS_MOVENOTIFY, 0 );
WinRegisterClass(hab, "InfoChild", ChildProc, 0, 6 );

hwndFrame = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE,
&flFrameFlags, pszClientClass, pszClientClass,
0L, 0, 1, &hwndClient );

/* Add our title to the task list maintained by Task Manager */
hwndIcon = WinLoadPointer( HWND_DESKTOP, 0, 1 );
SwitchList( hwndFrame, hwndIcon );

SizeTheWindow( hwndFrame );

CreateChildren( hwndClient );
ToggleFrameControls( hwndFrame );

WinStartTimer (hab, hwndClient, ID_TIMER, 750 );

while (WinGetMsg (hab, &qmsg, NULL, 0, 0 ) )
WinDispatchMsg (hab, &qmsg) ;

WinStopTimer (hab, hwndClient, ID_TIMER) ;

// store the calibration value on exit
sprintf( achBuf, "%lu", uCalibVal );
PrfWriteProfileString( HINI_USERPROFILE, "System Info",
"Calibration Value", achBuf );

WinDestroyWindow( hwndFrame );
WinDestroyMsgQueue( hmq );
WinDestroyPointer( hwndIcon );
WinTerminate( hab );
DosExit( EXIT_PROCESS, 0 );
}

/*
Function: SizeTheWindow

Description:
Set the initial size of the window at 2.5 character heights and for the
entire width of the display. Positions it at the top of the screen.

Values Returned:
None

Notes:
I stole this code from a petzold sample.

*/


VOID SizeTheWindow (HWND hwndFrame)

{
USHORT usCxScreen, usCyScreen, usCyBorder;
RECTL rcl;

usCxScreen = (USHORT)WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
usCyScreen = (USHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
usCyBorder = (USHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER );

rcl.yBottom = 0 ;
rcl.yTop = 2 * cyChar;
rcl.xLeft = 0 ;
rcl.xRight = usCyScreen - 2 * usCyBorder;

/* now figure out the size of the frame rectangle */
WinCalcFrameRect( hwndFrame, &rcl, FALSE );

/* ... and shift to the top line of the screen */
rcl.yBottom = usCyScreen - (rcl.yTop - rcl.yBottom);
rcl.yTop = usCyScreen;
rcl.xRight = usCxScreen;
rcl.xLeft = 0;

WinSetWindowPos (hwndFrame, NULL, (SHORT) rcl.xLeft, (SHORT) rcl.yBottom,
(SHORT) (rcl.xRight - rcl.xLeft),
(SHORT) (rcl.yTop - rcl.yBottom), SWP_SIZE | SWP_MOVE) ;
}

/*
Function: ClientWndProc

Description:
Window procedure for the main window. Really does very little except
call other functions to do something useful.

Values Returned:
MRESULTS

Notes:

*/

MRESULT EXPENTRY ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
static SHORT sTicks = 0;

switch (msg)
{
case WM_CREATE:
GetFontInfo( hwnd, &cyChar, &cxChar, &cyDesc );
return 0;

case WM_BUTTON1DOWN:
if ( fHidden )
return WinSendMsg( hwndFrame, WM_TRACKFRAME,
(MPARAM)( SHORT1FROMMP(mp2) | TF_MOVE ), NULL );
return 0;

case WM_BUTTON1DBLCLK:
ToggleFrameControls( hwndFrame );
return 0;

case WM_TIMER:
if ( (sTicks % 4) == 0 ) // every three seconds do the disk parms
UpdateLong( hwndChild );
UpdateShort( hwndChild );
sTicks++;
return 0;

case WM_ERASEBACKGROUND:
return MRFROMSHORT(TRUE);
}

return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
}



/*
Function: SwitchList

Description:
Add our program name to the switch list maintained by the system.

Values Returned:
None

Notes:

*/

void SwitchList( HWND hwndFrame, HPOINTER hptrIcon )

{
SWCNTRL swctl; /* switch list entry structure */

WinQueryWindowProcess( hwndFrame, &swctl.idProcess, NULL );
swctl.idSession = 0;
swctl.fReserved = 0;
swctl.hprog = NULL;
swctl.hwnd = hwndFrame;
swctl.hwndIcon = hptrIcon;
swctl.uchVisibility = SWL_VISIBLE;
swctl.fbJump = SWL_JUMPABLE;
strcpy( swctl.szSwtitle, "System Information" );

WinAddSwitchEntry( &swctl );

return;
}

/*
Function: CountCyc

Description:
Separate thread that runs at idle class, priority one. Since the system
provides an idle class, priority zero thread, setting it to one gives
a better value for idle time.

Simply counts iterations of a loop every 750 milliseconds. That value
is then compared to the number of iterations we were able to do when
the system was idle.

Values Returned:
None

Notes:

*/


void far cdecl CountCyc( PVOID nl )

{
SEL selGlobalSeg, /* selector num for global info seg */
selLocalSeg; /* selector num for local info seg */
GINFOSEG FAR *pgis; /* pointer to the global info seg */
ULONG lMils;
ULONG uBldVal;

DosGetInfoSeg(&selGlobalSeg, &selLocalSeg); /* get local & global info segs */
pgis = MAKEPGINFOSEG( selGlobalSeg ); /* get a pointer to the global */

if ( uCalibVal == 0L )
{
DosEnterCritSec();
DosSetPrty( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0 );

lMils = pgis->msecs + 3750;
while( pgis->msecs < lMils )
uCalibVal++;

DosExitCritSec();
uCalibVal /= 5;
}

// set priority to idle, 1 so that we avoid conflict with system idle thread.
DosSetPrty( PRTYS_THREAD, PRTYC_IDLETIME, PRTYD_MINIMUM, 0 );
DosSetPrty( PRTYS_THREAD, PRTYC_IDLETIME, 1, 0 );
while( 1 )
{
lMils = pgis->msecs + 750;
uBldVal = 0L;
while( pgis->msecs < lMils )
uBldVal++;

uCurVal = uBldVal;
}

}


/*
Function: ComputeFree

Description:
Compute free space on the specified drive. Set the free space as
a float point value representing free MB.

Values Returned:
0 - drive has more the 10% free
1 - drive is within 10% of being full

Notes:

*/

int ComputeFree( short DriveNum, float *fAvail )

{
FSALLOCATE fsaBuf;
float fTotFree;

DosQFSInfo( DriveNum, 1, (PCHAR)&fsaBuf, sizeof( fsaBuf ) );
fTotFree = (float)fsaBuf.cbSector * (float)fsaBuf.cSectorUnit *
(float)fsaBuf.cUnitAvail;
fTotFree /= (float)0x100000;

*fAvail = fTotFree;

if ( fsaBuf.cUnitAvail * 10 < fsaBuf.cUnit )
return( 1 ); /* less than 10% space free */
else
return( 0 );
}


/*
Function: GetFontInfo

Description:

Call WinQueryFontMetrics to determine information about the system font

Values Returned:
None.

Notes:

*/

void GetFontInfo( HWND hwnd, USHORT *cy, USHORT *cx, USHORT *cd )

{
HPS hps; /* need a ps before calling font metrics */
FONTMETRICS fm; /* info about the current font */


hps = WinGetPS( hwnd ); /* need a PS for query Font */
GpiQueryFontMetrics( hps, (LONG)sizeof(fm), &fm );
WinReleasePS( hps ); /* done with the ps now */

*cy = (SHORT)fm.lMaxBaselineExt; /* max height of one character */
*cx = (SHORT)fm.lAveCharWidth; /* average width of a character */
*cd = (SHORT)fm.lMaxDescender; /* max descender of a char */

return;
}


/*
Function: CreateChildren

Description:
Create the ten child windows in a double row. All windows are static
text. The leftmost windows are aligned on the left, the rightmost on the
right, all others are centered.

Values Returned:
0 - no error
1 - error

Notes:

*/


SHORT CreateChildren( HWND hwndParent )

{
short i, x, y, cx, cy;
SWP swp;

WinQueryWindowPos( hwndParent, &swp );

for( i = 0; i < 10; i+= 2 )
{
x = (swp.cx / 5) * (i/2);
y = 0;
cx = swp.cx / 5;
cy = swp.cy / 2;

hwndChild[i] = WinCreateWindow( hwndParent, "InfoChild", NULL,
WS_VISIBLE, x, y, cx, cy, NULL, HWND_TOP, i, NULL, NULL );
WinSetWindowPtr( hwndChild[i], 2, malloc( 100 ) );

y = swp.cy / 2;
hwndChild[i + 1] = WinCreateWindow( hwndParent, "InfoChild", NULL,
WS_VISIBLE, x, y, cx, cy, NULL, HWND_TOP, i + 1, NULL, NULL );
WinSetWindowPtr( hwndChild[i + 1], 2, malloc( 100 ) );
if ( hwndChild[ i ] == NULL || hwndChild[ i + 1 ] == NULL )
return 1;
}

strcpy( WinQueryWindowPtr( hwndChild[ CH_CPUTEXT ], 2 ), "CPU Usage" );
strcpy( WinQueryWindowPtr( hwndChild[ CH_MEMTEXT ], 2 ), "Free Memory" );
strcpy( WinQueryWindowPtr( hwndChild[ CH_SWAPTEXT ], 2 ), "Swap File Size" );
strcpy( WinQueryWindowPtr( hwndChild[ CH_DISKTEXT ], 2 ), "Free Disk Space" );
strcpy( WinQueryWindowPtr( hwndChild[ CH_CLOCKTEXT ], 2 ), "Time of day" );
strcpy( WinQueryWindowPtr( hwndChild[ CH_CPUVAL ], 2 ), "" );
strcpy( WinQueryWindowPtr( hwndChild[ CH_MEMVAL ], 2 ), "" );
strcpy( WinQueryWindowPtr( hwndChild[ CH_SWAPVAL ], 2 ), "" );
strcpy( WinQueryWindowPtr( hwndChild[ CH_DISKVAL ], 2 ), "" );
strcpy( WinQueryWindowPtr( hwndChild[ CH_CLOCKVAL ], 2 ), "" );

UpdateShort( hwndChild );
UpdateLong( hwndChild );
return 0;
}



/*
Function: ToggleFrameControls

Description:
if frame controls are hidden, restore them, if visible hide them.


Values Returned:
None

Notes:
I stole this code from an MS sample
*/



VOID ToggleFrameControls( HWND hwndFrame )

{

if ( !fHidden ) // hide the controls
{
hwndTitle = WinWindowFromID( hwndFrame, FID_TITLEBAR );
hwndSys = WinWindowFromID( hwndFrame, FID_SYSMENU );
hwndMin = WinWindowFromID( hwndFrame, FID_MINMAX );

WinSetParent( hwndTitle, HWND_OBJECT, FALSE );
WinSetParent( hwndSys, HWND_OBJECT, FALSE );
WinSetParent( hwndMin, HWND_OBJECT, FALSE );

WinSendMsg( hwndFrame, WM_UPDATEFRAME, (MPARAM)(FCF_TITLEBAR | FCF_SYSMENU | FCF_MINBUTTON),
NULL ) ;
fHidden = TRUE;

SizeTheWindow( hwndFrame );
}
else
{
WinSetParent( hwndTitle, hwndFrame, FALSE );
WinSetParent( hwndSys, hwndFrame, FALSE );
WinSetParent( hwndMin, hwndFrame, FALSE );

WinSendMsg( hwndFrame, WM_UPDATEFRAME, (MPARAM)(FCF_TITLEBAR | FCF_SYSMENU | FCF_MINBUTTON),
NULL );
fHidden = FALSE;
SizeTheWindow( hwndFrame );
}

return;
}

/*
Function: UpdateLong

Description:
Update the parameters that are done every three seconds -- swap file,
disk space.

Values Returned:
None

Notes:

*/




VOID UpdateLong( PHWND ahwndChild )

{
float fTmp;
CHAR achSpace[20];
FILESTATUS fs;

fTmp = fFreeSpace;
fIsRed = ComputeFree( usDriveNum, &fFreeSpace );
if ( fFreeSpace != fTmp ) // drive space has changed
{
if ( fIsRed )
WinSetWindowUShort( ahwndChild[ CH_DISKVAL ], 0, 1 );
else
WinSetWindowUShort( ahwndChild[ CH_DISKVAL ], 0, 0 );
sprintf( achSpace, "%c: %3.1f MB", usDriveNum + 'A' - 1, fFreeSpace );
strcpy( WinQueryWindowPtr( ahwndChild[ CH_DISKVAL ], 2 ), achSpace );
WinInvalidateRect( ahwndChild[ CH_DISKVAL ], NULL, 0 );
}

DosQPathInfo( SWAPFILE, FIL_STANDARD, (PBYTE)&fs, sizeof(fs), 0L );
if ( ulSwapSize != fs.cbFile )
{
ulSwapSize = fs.cbFile;
sprintf( achSpace, "%4.0f KB", (float)ulSwapSize / 1024.0 );
strcpy( WinQueryWindowPtr( ahwndChild[ CH_SWAPVAL ], 2 ), achSpace );
WinInvalidateRect( ahwndChild[ CH_SWAPVAL ], NULL, 0 );
}

return;
}

/*
Function: UpdateShort

Description:
Updates the parameters that are done on a .75 second basis - free memory,
time of day, CPU usage

Values Returned:
None

Notes:

*/

VOID UpdateShort( PHWND ahwndChild )

{
ULONG ulCur;
CHAR achFmt[25];
struct tm *tml;
time_t timer;

while ( uCalibVal == 0L )
DosSleep( 100L );

ulCur = (uCurVal * 100L) / uCalibVal;
if ( ulLast != ulCur )
{
sprintf( achFmt, "%ld%%", 100L - ulCur );
strcpy( WinQueryWindowPtr( ahwndChild[ CH_CPUVAL ], 2 ), achFmt );
WinInvalidateRect( ahwndChild[ CH_CPUVAL ], NULL, 0 );
ulLast = ulCur;
}

time( &timer );
tml = localtime( &timer );
ctime( &timer );
if ( tml->tm_hour == 0 )
sprintf( achFmt, "12:%02d:%02d AM", tml->tm_min, tml->tm_sec );
else if ( tml->tm_hour < 12 )
sprintf( achFmt, "%02d:%02d:%02d AM", tml->tm_hour, tml->tm_min, tml->tm_sec );
else if ( tml->tm_hour == 12 )
sprintf( achFmt, "12:%02d:%02d PM", tml->tm_min, tml->tm_sec );
else
sprintf( achFmt, "%02d:%02d:%02d PM", tml->tm_hour - 12, tml->tm_min, tml->tm_sec );
strcpy( WinQueryWindowPtr( ahwndChild[ CH_CLOCKVAL ], 2 ), achFmt );
WinInvalidateRect( ahwndChild[ CH_CLOCKVAL ], NULL, 0 );

DosMemAvail( &ulCur );
if ( ulCur != ulFrSize )
{
sprintf( achFmt, "%4ld KB", (ulCur + 512) / 1024 );
strcpy( WinQueryWindowPtr( ahwndChild[ CH_MEMVAL ], 2 ), achFmt );
WinInvalidateRect( ahwndChild[ CH_MEMVAL ], NULL, 0 );
ulFrSize = ulCur;
}
return;
}



/*
Function: ChildProc

Description:
Child window that is extremely stupid -- knows how to display centered
text in its window

Values Returned:
MRESULTS

Notes:

*/

MRESULT EXPENTRY ChildProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )

{
HPS hps;
RECTL rcl;
LONG lCol;
PCHAR pch;

switch( msg )
{
case WM_CREATE:
WinSetWindowUShort( hwnd, 0, 0 );
return 0;

case WM_BUTTON1DBLCLK:
case WM_BUTTON1DOWN:
WinSendMsg( WinQueryWindow( hwnd, QW_PARENT, 0 ), msg, mp1, mp2 );
return 0;

case WM_DESTROY:
free( WinQueryWindowPtr( hwnd, 2 ) );
return 0;

case WM_PAINT:
pch = WinQueryWindowPtr( hwnd, 2 );
WinQueryWindowRect( hwnd, &rcl );
hps = WinBeginPaint( hwnd, NULL, NULL );
if ( WinQueryWindowUShort( hwnd, 0 ) == 0 )
lCol = CLR_NEUTRAL;
else
lCol = CLR_RED;
WinDrawText( hps, -1, pch, &rcl, lCol, CLR_BACKGROUND,
DT_VCENTER | DT_CENTER | DT_ERASERECT );
WinEndPaint( hps );
return 0;
}

return WinDefWindowProc( hwnd, msg, mp1, mp2 );
}


  3 Responses to “Category : OS/2 Files
Archive   : SYSINFO.ZIP
Filename : SYSINFO.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/