📄 smartmon.c
字号:
if ( hPrevInstance ) {
MessageBox( (HWND)NULL, (LPSTR)"SmartMon is already running.",
(LPSTR)szTitle, MB_ICONINFORMATION );
return FALSE;
}
//
// Don't allow app to run if SmartDrive is not installed.
//
if ( get_cache_hits() == -1L ) {
MessageBox( (HWND)NULL, (LPSTR)"SmartDrive is not installed.",
(LPSTR)szTitle, MB_ICONINFORMATION );
return FALSE;
}
//
// Get cache size
//
BlockSize = get_cache_info( &DosBlocks, &WinBlocks );
DosCacheSize = (DWORD)DosBlocks * (DWORD)BlockSize / 1024;
WinCacheSize = (DWORD)WinBlocks * (DWORD)BlockSize / 1024;
//
// Compose default DOS batch filename (for saving drive settings).
// The default is AUTOEXEC.BAT on the boot drive. If we can't
// identify the boot drive, then assume the first hard disk.
//
if ( LOBYTE(get_dos_version()) >= 4 )
cBootDrv = get_boot_drive() - 1 + 'a';
else {
CurDriveCount = count_valid_drives( CurDriveList );
cBootDrv = 'c';
for ( i = 0; i < CurDriveCount; i++ ) {
iDrv = CurDriveList[i+1];
iDrvIndex = GetDriveIndex( iDrv, GetDriveType( iDrv ) );
if ( iDrvIndex == HARDDRVBMP ) {
cBootDrv = iDrv + 'a';
break;
}
}
}
wsprintf( szBatchFile, "%c:\\autoexec.bat", cBootDrv );
//
// Initialize all random things here
//
wWinVer = GetVersion();
fUpdateIconBackground = FALSE;
fTopMostChanged = FALSE;
fLogging = FALSE;
UpdateHelpMessage( IDS_TITLE );
hbmpIconDrv = hbmpIdle;
fProfileChanged = FALSE;
fAlreadyIdle = FALSE;
fDriveInfoChanged = FALSE;
InitDriveBitmap();
fTopMost = TRUE;
GetProfileSettings();
return TRUE;
}
#ifdef OBSOLETE
/**************************************************************************/
/*** ***/
/*** UpdateStat ***/
/*** ***/
/*** This routine displays the hit/miss count and ratio is simple ***/
/*** text format. ***/
/*** ***/
/*** Note that it might be a good idea to activate this code when ***/
/*** InitRateBox fails for some reason (like low memory). ***/
/*** ***/
/**************************************************************************/
void UpdateStat( HWND hWnd )
{
DWORD hits, misses, rate;
//
// Get cache status
//
hits = get_cache_hits();
misses = get_cache_misses();
rate = (hits * 100) / (hits + misses);
//
// Display cache status
//
wsprintf( szBuffer, "%lu", hits );
SetDlgItemText( hWnd, IDD_HITS, szBuffer );
wsprintf( szBuffer, "%lu", misses );
SetDlgItemText( hWnd, IDD_MISSES, szBuffer );
wsprintf( szBuffer, "%lu%%", rate );
SetDlgItemText( hWnd, IDD_RATE, szBuffer );
}
#endif
/**************************************************************************/
/*** ***/
/*** DoDriveControl ***/
/*** ***/
/*** This routine changes the caching status of each drive as ***/
/*** the user manipulates the corresponding radio buttons. ***/
/*** ***/
/*** Since the caching status, as well as drive configuration ***/
/*** can be changed outside of SMARTMON, this routine should ***/
/*** be called to do a GET whenever we get focus back. ***/
/*** ***/
/**************************************************************************/
void DoDriveControl( HWND hWnd, WORD cmd, WORD id )
{
extern WORD cCurDriveSel;
WORD status;
WORD iCurDrvIndex;
HWND hCtl;
hCtl = GetDlgItem( hWnd, IDD_DRIVEID );
SendMessage( hCtl, CB_GETLBTEXT,
(WPARAM)(DWORD)SendMessage(hCtl, CB_GETCURSEL,0,0),
(LPARAM)(LPSTR)szBuffer );
cCurDriveSel = szBuffer[0] - 'a';
if ( cmd == GET ) {
status = cache_a_drive( GET, cCurDriveSel );
if ( status & NO_READ )
id = IDD_NOCACHING;
else if ( status & NO_WRITE )
id = IDD_READONLY;
else
id = IDD_READWRITE;
//
// Disable r/o and r/w buttons if drive cannot be cached.
//
iCurDrvIndex = GetDriveIndex( cCurDriveSel, GetDriveType( cCurDriveSel ) );
if ( (iCurDrvIndex == FLOPPYBMP) ||
((iCurDrvIndex == HARDDRVBMP) && !CheckForStacker(cCurDriveSel))) {
EnableWindow( GetDlgItem(hWnd, IDD_READONLY), TRUE );
EnableWindow( GetDlgItem(hWnd, IDD_READWRITE), TRUE );
EnableWindow( GetDlgItem(hWnd, IDD_NOCACHING), TRUE );
} else {
EnableWindow( GetDlgItem(hWnd, IDD_READONLY), FALSE );
EnableWindow( GetDlgItem(hWnd, IDD_READWRITE), FALSE );
EnableWindow( GetDlgItem(hWnd, IDD_NOCACHING), FALSE );
}
} else { // Set operation
//
// Get into a known state, then disable selectively
//
cache_a_drive( ENABLE_READ, cCurDriveSel );
cache_a_drive( ENABLE_WRITE, cCurDriveSel );
if ( id != IDD_READWRITE ) {
cache_a_drive( DISABLE_WRITE, cCurDriveSel );
if ( id == IDD_NOCACHING )
cache_a_drive( DISABLE_READ, cCurDriveSel );
}
fDriveInfoChanged = TRUE;
UpdateHelpMessage( IDS_STATUS );
}
CheckRadioButton( hWnd, IDD_READONLY, IDD_NOCACHING, id );
}
/**************************************************************************/
/*** ***/
/*** UpdateMemorySize ***/
/*** ***/
/*** This routine displays the cache memory size under DOS and ***/
/*** under Windows. Currently the size cannot be changed when ***/
/*** Windows is running. ***/
/*** ***/
/**************************************************************************/
void UpdateMemorySize( HWND hWnd )
{
wsprintf( szBuffer, "%uK", DosCacheSize );
SetDlgItemText( hWnd, IDD_DOSSIZE, szBuffer );
wsprintf( szBuffer, "%uK", WinCacheSize );
SetDlgItemText( hWnd, IDD_WINSIZE, szBuffer );
}
/**************************************************************************/
/*** ***/
/*** DoHelp ***/
/*** ***/
/*** This routine invokes WINHELP if BOOL is true, or dismisses ***/
/*** it if BOOL is false. ***/
/*** ***/
/**************************************************************************/
void DoHelp( HWND hWnd, UINT cmd, DWORD data )
{
if ( LoadString(hInst, IDS_HELPFILE, szBuffer, sizeof(szBuffer)-1) )
WinHelp( hWnd, (LPSTR)szBuffer, cmd, data );
}
/**************************************************************************/
/*** ***/
/*** OptionsDlgProc ***/
/*** ***/
/**************************************************************************/
BOOL FAR PASCAL OptionsDlgProc( hDlg, msg, wParam, lParam )
HWND hDlg;
WORD msg;
WPARAM wParam;
LPARAM lParam;
{
OFSTRUCT of;
int rc;
WORD val;
BOOL bRet;
HWND hCtl;
switch ( msg )
{
case WM_INITDIALOG:
SetDlgItemInt( hDlg, IDD_MSEC, Frequency, FALSE );
SetDlgItemInt( hDlg, IDD_INTERVAL, SpecInterval, FALSE );
SetDlgItemText( hDlg, IDD_LOGFILE, szLogFile );
CheckDlgButton( hDlg, IDD_AUTOSTOP, fAutoStop );
SetDlgItemInt( hDlg, IDD_STOPTIME, AutoLogTime, FALSE );
CheckDlgButton( hDlg, IDD_SAVESET, fUpdateAuto );
SetDlgItemText( hDlg, IDD_BATCHFILE, szBatchFile );
break;
case WM_COMMAND:
switch( wParam )
{
case IDD_HELP:
DoHelp( hDlg, HELP_CONTEXT, 1L );
break;
case IDD_AUTOSTOP:
CheckDlgButton( hDlg, IDD_AUTOSTOP,
!IsDlgButtonChecked(hDlg, IDD_AUTOSTOP) );
break;
case IDD_SAVESET:
CheckDlgButton( hDlg, IDD_SAVESET,
!IsDlgButtonChecked(hDlg, IDD_SAVESET) );
break;
case IDOK:
//
// Reset sampling frequency
//
val = GetDlgItemInt( hDlg, IDD_MSEC, (BOOL FAR*)&bRet, FALSE );
if ( bRet ) {
if ( val > MAX_FREQUENCY )
val = MAX_FREQUENCY;
if ( val < MIN_FREQUENCY )
val = MIN_FREQUENCY;
if ( val != Frequency ) {
Frequency = val;
KillTimer( hWndMain, 0 );
SetTimer( hWndMain, 0, Frequency, NULL );
wsprintf( szBuffer, "%u msec", Frequency );
SetDlgItemText( hWndMain, IDD_SAMPFREQ, szBuffer );
}
}
//
// Reset display interval
//
val = GetDlgItemInt( hDlg, IDD_INTERVAL, (BOOL FAR*)&bRet, FALSE );
if ( bRet ) {
if ( val > MAX_INTERVAL )
val = MAX_INTERVAL;
if ( val < MIN_INTERVAL )
val = MIN_INTERVAL;
if ( val != SpecInterval ) {
SpecInterval = val;
hCtl = GetDlgItem( hWndMain, IDD_CHARTBOX );
ResetRateChart( hCtl );
InvalidateRect( hCtl, (LPRECT)NULL, TRUE );
}
}
GetDlgItemText( hDlg, IDD_LOGFILE, szLogFile, MAXFILENAMELEN );
fAutoStop = IsDlgButtonChecked( hDlg, IDD_AUTOSTOP );
val = GetDlgItemInt( hDlg, IDD_STOPTIME, (BOOL FAR *)&bRet, FALSE );
if ( bRet )
AutoLogTime = val;
if ( AutoLogTime > MAX_AUTOLOGTIME )
AutoLogTime = MAX_AUTOLOGTIME;
if ( AutoLogTime < MIN_AUTOLOGTIME )
AutoLogTime = MIN_AUTOLOGTIME;
if ( fLogging )
LogStopTime = LogStartTime + AutoLogTime * 60000;
fUpdateAuto = IsDlgButtonChecked( hDlg, IDD_SAVESET );
GetDlgItemText( hDlg, IDD_BATCHFILE, szBuffer, BUFLEN );
rc = OpenFile( (LPSTR)szBuffer, (OFSTRUCT FAR *)&of, OF_EXIST );
SetDlgItemText( hDlg, IDD_BATCHFILE, of.szPathName );
OemToAnsi( of.szPathName, szBatchFile );
if ( fUpdateAuto && (rc == -1) ) {
MessageBox( (HWND)NULL, (LPSTR)"Batch file does not exist.",
(LPSTR)szTitle, MB_ICONINFORMATION );
return TRUE;
}
SaveProfileSettings();
// fall through
case IDCANCEL:
DoHelp( hDlg, HELP_QUIT, 0L );
EndDialog( hDlg, 0 );
break;
}
break;
default:
return FALSE; // message not processed
}
return TRUE; // message processed
}
/**************************************************************************/
/*** ***/
/*** CheckAutoStop ***/
/*** ***/
/*** This routine stops logging to file. Note that the logging ***/
/*** auto stop time may be altered through the options box after ***/
/*** logging has been started. ***/
/*** ***/
/**************************************************************************/
void CheckAutoStop( HWND hWnd )
{
if ( fLogging && fAutoStop )
//
// Note, this logic will fail if tick counter wraps around
//
if ( GetTickCount() > LogStopTime )
PostMessage( hWnd, WM_COMMAND, IDD_STOPLOG, 0L );
}
/**************************************************************************/
/*** ***/
/*** GetProfileSettings ***/
/*** SaveProfileSettings ***/
/*** ***/
/*** Get and save settings to WIN.INI. ***/
/*** ***/
/**************************************************************************/
void GetProfileSettings()
{
//
// Retrieve option settings from WIN.INI
//
SpecInterval = GetProfileInt( szProSec, szInterval, DEF_INTERVAL );
Frequency = GetProfileInt( szProSec, szFreq, DEF_FREQUENCY );
fAutoStop = GetProfileInt( szProSec, szfStop, DEF_AUTOSTOP );
AutoLogTime = GetProfileInt( szProSec, szLogTime, DEF_LOGTIME );
fUpdateAuto = GetProfileInt( szProSec, szUpdateDOS, DEF_UPDATEDOS );
fTopMost = GetProfileInt( szProSec, szTopMost, DEF_TOPMOST );
if ( GetProfileString( szProSec, szLog, szLogFile, szBuffer, BUFLEN ) )
lstrcpy( szLogFile, szBuffer );
if ( GetProfileString( szProSec, szBatch, szBatchFile, szBuffer, BUFLEN ) )
lstrcpy( szBatchFile, szBuffer );
}
void SaveProfileSettings()
{
//
// Save option settings to profile
//
wsprintf( szBuffer, "%u", SpecInterval );
WriteProfileString( szProSec, szInterval, szBuffer );
wsprintf( szBuffer, "%u", Frequency );
WriteProfileString( szProSec, szFreq, szBuffer );
wsprintf( szBuffer, "%u", fAutoStop );
WriteProfileString( szProSec, szfStop, szBuffer );
wsprintf( szBuffer, "%u", AutoLogTime );
WriteProfileString( szProSec, szLogTime, szBuffer );
wsprintf( szBuffer, "%u", fUpdateAuto );
WriteProfileString( szProSec, szUpdateDOS, szBuffer );
wsprintf( szBuffer, "%u", fTopMost );
WriteProfileString( szProSec, szTopMost, szBuffer );
WriteProfileString( szProSec, szLog, szLogFile );
WriteProfileString( szProSec, szBatch, szBatchFile );
}
/**************************************************************************/
/*** ***/
/*** CheckForStacker ***/
/*** ***/
/*** This routine does an absolute disk read (INT 25) of the ***/
/*** first sector, and checks the disk label to see if it is ***/
/*** a Stacker volume. We allocate an 8K buffer to serve as ***/
/*** the DTA (same as WINFILE), hope it's big enough for all ***/
/*** disks. ***/
/*** ***/
/**************************************************************************/
BOOL CheckForStacker( WORD cDrv )
{
HANDLE hBuf;
LPSTR pBuf;
BOOL rc;
//
// If can't allocate DTA to do int 25, assume not Stacker
//
if (! (hBuf = GlobalAlloc( GHND, 8192L )) )
return FALSE;
pBuf = GlobalLock( hBuf );
rc = is_Stacker_drive( cDrv, pBuf );
GlobalUnlock( hBuf );
GlobalFree( hBuf );
return rc;
}
void DoTopMost( HWND hWnd )
{
fTopMostChanged = TRUE;
fTopMost = fTopMost ? FALSE : TRUE;
CheckMenuItem( hSysMenu, IDD_TOPMOST, fTopMost? MF_CHECKED : MF_UNCHECKED );
if ( !fTopMost ) {
SetWindowPos( hWnd, HWND_BOTTOM, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW );
SetWindowPos( hWnd, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE );
} else
SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -