windows-nt/Source/XPSP1/NT/sdktools/proccon/clitool/clitool.cpp

2174 lines
97 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*======================================================================================//
| //
|Copyright (c) 1998, 1999 Sequent Computer Systems, Incorporated. All rights reserved. //
| //
|Description: //
| //
| Windows 2000 Process Control command line utility //
| //
|Created: //
| //
| Jarl McDonald 07-98 //
| //
|Revision History: //
| //
| Jarl McDonald Spring, 1999 Completed version 1.0 changes //
| //
|=======================================================================================*/
#include <windows.h>
#include <stdio.h>
#include <stddef.h>
#include <tchar.h>
#include <shellapi.h>
#include "resource.h"
#include "..\Library\ProcConAPI.h"
//=======================================================================================
// Macros...
//=======================================================================================
#define ENTRY_COUNT(x) (int)((sizeof(x) / sizeof(x[0])))
#define SPACE TEXT(' ')
//=======================================================================================
// enums, typedefs, etc....
//=======================================================================================
enum _HELP_FLAGS {
HELP_LIST = 0x01,
HELP_MGMT = 0x02,
HELP_ALIAS = 0x04,
} HELP_FLAGS;
typedef enum _switches { // Do not localize these...
COMPUTER_NAME = TEXT('c'),
BUFFER_SIZE = TEXT('b'),
INTERACTIVE = TEXT('i'),
FILE_INPUT = TEXT('f'),
ADMIN_DUMPREST = TEXT('x'),
OP_ADD = TEXT('a'),
OP_REP = TEXT('r'),
OP_DEL = TEXT('d'),
OP_SWAP = TEXT('s'),
OP_LIST = TEXT('l'),
OP_UPDATE = TEXT('u'),
OP_COMMENT = TEXT('*'),
OP_KILL = TEXT('k'),
OP_HELP = TEXT('?'),
OP_HELP2 = TEXT('h'),
DATA_GROUP = TEXT('g'),
DATA_PROC = TEXT('p'),
DATA_NAME = TEXT('n'),
DATA_DUMPREST = TEXT(';'),
DATA_SERVICE = TEXT('v'),
DATA_MEDIATOR = TEXT('m'),
SUB_DEFS = TEXT('d'),
SUB_SUMMARY = TEXT('s'),
SUB_LIST = TEXT('l'),
SUB_FULLNAMES = TEXT('f'),
SUB_RUNNING = TEXT('r'),
SUB_ONLY = TEXT('o'),
};
typedef enum _defSwitches { // Do not localize these...
DEF_FLAGS = TEXT('f'),
DEF_PRIO = TEXT('p'),
DEF_AFF = TEXT('a'),
DEF_WS = TEXT('w'),
DEF_SCHED = TEXT('s'),
DEF_DESC = TEXT('d'),
DEF_PROCTIME = TEXT('t'),
DEF_GROUPTIME = TEXT('u'),
DEF_GROUPMEM = TEXT('n'),
DEF_PROCMEM = TEXT('m'),
DEF_PROCCOUNT = TEXT('c'),
DEF_BRKAWAY = TEXT('b'),
DEF_SILENTBRKAWAY = TEXT('q'),
DEF_DIEONUHEX = TEXT('x'),
DEF_CLOSEONEMPTY = TEXT('y'),
DEF_MSGONGRPTIME = TEXT('z'),
DEF_GROUP = TEXT('g'),
DEF_VARDATA = TEXT('v'),
DEF_PROF = TEXT('r'),
};
typedef enum _groupListSwitches { // Do not localize these...
GL_ALL = TEXT('a'),
GL_BASE = TEXT('b'),
GL_IO = TEXT('i'),
GL_MEMORY = TEXT('m'),
GL_PROCESS = TEXT('p'),
GL_TIME = TEXT('t'),
};
typedef enum _colJustify {
PCCOL_JUST_CENTER = 1,
PCCOL_JUST_LEFT,
PCCOL_JUST_RIGHT
};
typedef struct _PCTableDef {
PCULONG32 longStringID, shortStringID;
PCULONG32 longMinLen, shortMinLen;
PCULONG32 justification;
TCHAR rowFmt[32];
} PCTableDef;
//=======================================================================================
// Global data...
//=======================================================================================
static TCHAR SUB_DefSummaryList[] = { SUB_DEFS, SUB_SUMMARY, SUB_LIST, 0 };
static int pCode[] = { PCPrioIdle, PCPrioIdle, PCPrioNormal, PCPrioHigh,
PCPrioRealTime, PCPrioAboveNormal, PCPrioBelowNormal };
// L ("Low") is a synonym for idle prio class. Do not localize these...
static TCHAR pNames[] = TEXT("LINHRAB");
TCHAR oldTarget[MAX_PATH] = TEXT("\0");
TCHAR target[MAX_PATH] = TEXT(".");
PCid targId = 0;
PCINT32 oldBuffer = 0;
PCINT32 buffer = 64500;
BOOL convertError = FALSE;
BOOL interact = FALSE;
FILE *inFile = NULL;
TCHAR inFileName[MAX_PATH];
FILE *adminFile = NULL;
TCHAR adminFileName[MAX_PATH];
PCNameRule nameRules[PC_MAX_BUF_SIZE / sizeof(PCNameRule)];
PCSystemInfo sysInfo;
HMODULE moduleUs = GetModuleHandle( NULL );
TCHAR cmdPrompt[32];
BOOL gListShowBase, gListShowIO, gListShowMem, gListShowProc, gListShowTime, gShowFmtProcTime, gShowFullNames;
PCULONG32 colWidth[32], colOffset[32], tableWidth;
TCHAR colHead[2048];
TCHAR colDash[2048];
TCHAR rowData[2048];
TCHAR sepChar = 0;
//=======================================================================================
// function prototypes....
//=======================================================================================
static int GetNextCommand ( FILE *readMe, TCHAR **list );
static int DoCommands ( int argct, TCHAR **argList );
static int DoDumpRestore ( FILE *adminFile, BOOL dump );
static int cFileError ( BOOL dump );
static void DispDumpComment ( FILE *adminFile, PCULONG32 msgID, PCINT32 count = 0 );
static void DumpMgmtParms ( MGMT_PARMS &mgt, PCINT16 len, TCHAR *data );
static void DoMediatorControl( TCHAR **pArgs, PCUINT32 pArgCt );
static TCHAR *GetOpName ( TCHAR code );
static TCHAR *GetDataName ( TCHAR code, TCHAR subCode );
static TCHAR *GetDataSubName ( TCHAR code );
static PC_MGMT_FLAGS GetMgtFlags( TCHAR *txt );
static void PrintHelp ( PCUINT32 flags, BOOL isGrp = TRUE, PCUINT32 msgId = 0 );
static void PrintLine ( TCHAR *data, PCUINT32 nlCount );
static void ShowNameRules ( PCNameRule *rule, PCINT32 count, PCINT32 index = 0 );
static void ShowGrpDetail ( PCJobDetail &grpDetail );
static void ShowProcDetail ( PCProcDetail &procDetail );
static void ShowGrpSummary ( PCJobSummary *list, PCINT32 count, BOOL isFirst = TRUE, int totcnt = 0 );
static void ShowProcSummary ( PCProcSummary *list, PCINT32 count, BOOL isFirst = TRUE, int totcnt = 0 );
static void ShowGrpList ( PCJobListItem *list, PCINT32 count, BOOL isFirst = TRUE, int totcnt = 0 );
static void ShowProcList ( PCProcListItem *list, PCINT32 count, BOOL isFirst = TRUE, int totcnt = 0 );
static void ShowGrpListWithBase( PCJobListItem *list, PCINT32 count, BOOL isFirst );
static void ShowGrpListWithIo ( PCJobListItem *list, PCINT32 count, BOOL isFirst );
static void ShowGrpListWithMem ( PCJobListItem *list, PCINT32 count, BOOL isFirst );
static void ShowGrpListWithProc( PCJobListItem *list, PCINT32 count, BOOL isFirst );
static void ShowGrpListWithTime( PCJobListItem *list, PCINT32 count, BOOL isFirst );
static void ShowMgmtParms ( MGMT_PARMS &parm, BOOL isGrp );
static void ShowMgmtParmsAsList( PCTableDef *table, PCULONG32 entries, PCULONG32 first, MGMT_PARMS &parm, BOOL isGrp );
static void ShowVariableData ( short len, TCHAR *data );
static void ShowListFlags ( PC_LIST_FLAGS flags, TCHAR out[8] );
static void ShowMgmtFlags ( TCHAR flags[16], PC_MGMT_FLAGS mFlags, BOOL compact = FALSE );
static void ShowSysInfo ( PCSystemInfo &sysInfo, BOOL versionOnly = TRUE );
static void ShowSysParms ( PCSystemParms &sysParms );
static int ShowHelp ( TCHAR **pArgs, PCUINT32 pArgCt );
static void ShowCLIHelp ( void );
static void ShowDetailHelp ( TCHAR **pArgs, PCUINT32 pArgCt );
static void BuildSystemParms ( PCSystemParms &newParms, TCHAR **pArgs, PCUINT32 pArgCt );
static void BuildNameRule ( PCNameRule &newRule, TCHAR **pArgs, PCUINT32 pArgCt );
static void BuildGrpDetail ( PCJobDetail &newDetail, TCHAR **pArgs, PCUINT32 pArgCt );
static void BuildProcDetail ( PCProcDetail &newDetail, TCHAR **pArgs, PCUINT32 pArgCt );
static void BuildGrpSummary ( PCJobSummary &newSummary, TCHAR **pArgs, PCUINT32 pArgCt, PCUINT32 *listFlags );
static void BuildProcSummary ( PCProcSummary &newSummary, TCHAR **pArgs, PCUINT32 pArgCt, PCUINT32 *listFlags );
static void BuildGrpListItem ( PCJobListItem &newListItem, TCHAR **pArgs, PCUINT32 pArgCt, PCUINT32 *listFlags );
static void BuildProcListItem ( PCProcListItem &newListItem, TCHAR **pArgs, PCUINT32 pArgCt, PCUINT32 *listFlags );
static void BuildMgmtParms ( MGMT_PARMS &parm, TCHAR **pArgs, PCUINT32 pArgCt,
JOB_NAME grpHere = NULL, PCINT16 *len = NULL, TCHAR *var = NULL );
static void BuildTableHeader ( PCTableDef *table, PCULONG32 entries, BOOL printIt = TRUE );
static void InsertTableData ( PCTableDef *table, PCULONG32 index, TCHAR *dataItem, BOOL printIt );
static void MergeGroupDetail ( PCJobDetail &newDet, PCJobDetail &oldDet );
static void MergeProcDetail ( PCProcDetail &newDet, PCProcDetail &oldDet );
//=======================================================================================
// Simple functions....
//=======================================================================================
#define TOOLMSG_ERR_BUFF_SIZE 4096
static LPTSTR GetErrorText( PCUINT32 error, LPTSTR buf, PCUINT32 size )
{
static TCHAR *errBuf;
PCUINT32 dwRet = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE + FORMAT_MESSAGE_FROM_SYSTEM +
FORMAT_MESSAGE_IGNORE_INSERTS + FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, error, 0, (TCHAR *) &errBuf, 0, NULL );
if ( !dwRet )
_sntprintf( buf, size, TEXT("No message text for error 0x%lx, format error 0x%lx"), error, GetLastError());
else {
_tcsncpy( buf, errBuf, size );
LocalFree( errBuf );
while ( --dwRet && (buf[dwRet] == TEXT('\n') || buf[dwRet] == TEXT('\r') || buf[dwRet] == TEXT('.')) )
buf[dwRet] = TEXT('\0');
}
return buf;
}
static int ToolMsg( PCUINT32 msgId, VOID *arg1 = NULL, PCINT32 err = ERROR_SUCCESS,
VOID *arg2 = NULL, VOID *arg3 = NULL, VOID *arg4 = NULL,
VOID *arg5 = NULL, VOID *arg6 = NULL, VOID *arg7 = NULL,
VOID *arg8 = NULL, VOID *arg9 = NULL, VOID *arg10 = NULL,
VOID *arg11 = NULL ) {
PCUINT32 nlCt = err == ERROR_SUCCESS? 1 : 0;
TCHAR *mBuf;
TCHAR eBuf[TOOLMSG_ERR_BUFF_SIZE], errBuf[TOOLMSG_ERR_BUFF_SIZE];
char *ptrs[16];
ptrs[0] = (char *) arg1;
ptrs[1] = (char *) arg2;
ptrs[2] = (char *) arg3;
ptrs[3] = (char *) arg4;
ptrs[4] = (char *) arg5;
ptrs[5] = (char *) arg6;
ptrs[6] = (char *) arg7;
ptrs[7] = (char *) arg8;
ptrs[8] = (char *) arg9;
ptrs[9] = (char *) arg10;
ptrs[10] = (char *) arg11;
PCUINT32 dwRet = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE + FORMAT_MESSAGE_ARGUMENT_ARRAY +
FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, msgId, 0, (TCHAR *) &mBuf, 0, ptrs );
if ( !dwRet ) {
PCUINT32 msgErr = GetLastError();
_stprintf( eBuf, TEXT("Message 0x%lx not found, message error is: %s."),
msgId, GetErrorText( msgErr, errBuf, TOOLMSG_ERR_BUFF_SIZE ));
PrintLine( eBuf, nlCt );
}
else {
while ( --dwRet && (mBuf[dwRet] == TEXT('\n') || mBuf[dwRet] == TEXT('\r')) )
mBuf[dwRet] = TEXT('\0');
if ( err != ERROR_SUCCESS && dwRet && mBuf[dwRet] == TEXT('.') )
mBuf[dwRet] = TEXT('\0');
PrintLine( mBuf, nlCt );
LocalFree( mBuf );
}
if ( err != ERROR_SUCCESS ) {
_stprintf( eBuf, TEXT(": %s (0x%lx)."), GetErrorText( err, errBuf, TOOLMSG_ERR_BUFF_SIZE ), err );
PrintLine( eBuf, 1 );
}
return err != ERROR_SUCCESS? err : ERROR_INVALID_PARAMETER;
}
static int ToolMsg( PCUINT32 msgId, int arg1 ) {
return ToolMsg( msgId, IntToPtr(arg1) );
}
static unsigned __int64 GetValue( TCHAR *data, unsigned __int64 limitValue ) {
BOOL hex = *data == TEXT('0') && _totlower(*(data + 1)) == TEXT('x');
if ( hex ) data += 2;
unsigned __int64 factor, result = 0, mult = 1;
ULONG digitMult = hex? 16 : 10;
for ( __int64 len = (__int64) _tcslen( data ) - 1; len >= 0; --len ) {
TCHAR c = _totlower( *(data + len) );
if ( hex && (c >= TEXT('a') && c <= TEXT('f')) )
factor = mult * (c - TEXT('a') + 10);
else if ( c >= TEXT('0') && c <= TEXT('9') )
factor = mult * (c - TEXT('0'));
else {
ToolMsg( hex? PCCLIMSG_INVALID_HEX_DIGIT : PCCLIMSG_INVALID_DEC_DIGIT, data + len );
convertError = TRUE;
continue;
}
if ( limitValue - result < factor ) {
ToolMsg( PCCLIMSG_NUM_TOO_LARGE, data );
convertError = TRUE;
return limitValue;
}
else {
result += factor;
mult *= digitMult;
}
}
return result;
}
static int GetInteger( TCHAR *data ) {
return (int) GetValue( data, 0x000000007fffffff );
}
static __int64 GetInteger64( TCHAR *data ) {
return (__int64) GetValue( data, 0x7fffffffffffffff );
}
static unsigned __int64 GetUInteger64( TCHAR *data ) {
return GetValue( data, 0xffffffffffffffff );
}
static int GetPriority( TCHAR *data ) {
TCHAR *c = _tcschr( pNames, _totupper( *data ) );
if ( c ) return pCode[ c - pNames ];
else return 0;
}
static TCHAR ShowPriority( int data ) {
for ( int i = 0; i < ENTRY_COUNT(pCode); ++i )
if ( data == pCode[i] ) return pNames[i];
return TEXT(' ');
}
static BOOL IsSwitch( TCHAR c ) {
return c == TEXT('-') || c == TEXT('/');
}
//=======================================================================================
// Main...
//=======================================================================================
int _cdecl main( void ) {
int argct, retCode = 0;
BOOL haveCmd = TRUE, firstPass = TRUE;
for ( TCHAR *cmdLine = GetCommandLineW(); haveCmd; haveCmd = GetNextCommand( inFile, &cmdLine ) ) {
TCHAR **argList = CommandLineToArgvW( cmdLine, &argct );
if (argList) {
if ( firstPass || !**argList ) retCode = DoCommands( argct - 1, argList + 1 );
else retCode = DoCommands( argct, argList );
GlobalFree( argList );
}
firstPass = FALSE;
}
if ( targId ) PCClose( targId );
if ( inFile ) fclose( inFile );
return retCode;
}
//=======================================================================================
// Processing functions...
//=======================================================================================
int GetNextCommand( FILE *readMe, TCHAR **cmd ) {
static TCHAR cmdLine[1024];
char cmdBuf[1024];
TCHAR *p = NULL;
if ( interact ) {
PrintLine( cmdPrompt, 0 );
if ( gets( cmdBuf ) ) {
OemToChar( cmdBuf, cmdLine );
p = *cmdLine? cmdLine : NULL;
}
}
else if ( readMe ) {
for ( ;; ) {
p = _fgetts( cmdLine, ENTRY_COUNT(cmdLine), readMe );
if ( !p ) break;
// MS RAID: #375579 - last character dropped when reading from file
size_t l = _tcscspn(p,TEXT("\r\n"));
*(p + l) = 0;
if ( *p ) break;
}
}
*cmd = p;
return p != NULL;
}
int DoCommands( int argct, TCHAR **argList ) {
PCINT32 numRules, updateCtr;
TCHAR opCode = OP_LIST;
TCHAR dataObj = 0;
TCHAR dataSubObj = 0;
PCINT32 index = 0;
TCHAR **pArgs = NULL;
PCUINT32 pArgCt = 0;
BOOL restIsData = FALSE, getListData = FALSE,
doDump = FALSE, doRestore = FALSE;
PCUINT32 listFlags = 0;
TCHAR sub;
gShowFullNames = convertError = FALSE;
// Process parameters until end of parameters...
for ( int i = 0; i < argct; ++i ) {
TCHAR *arg = *argList++;
if ( *arg == 0xfeff || *arg == 0xfffe ) ++arg; // ignore 'This is Unicode' prefix
if ( !IsSwitch( *arg ) )
return ToolMsg( PCCLIMSG_SWITCH_EXPECTED, arg );
TCHAR swChar = *++arg;
switch ( swChar ) {
case COMPUTER_NAME:
if ( *(arg + 1) ) return ToolMsg( PCCLIMSG_SWITCH_UNKNOWN, --arg );
if ( ++i >= argct )
return ToolMsg( PCCLIMSG_ARG_MISSING, --arg );
_tcscpy( target, *argList++);
break;
case BUFFER_SIZE:
if ( *(arg + 1) ) return ToolMsg( PCCLIMSG_SWITCH_UNKNOWN, --arg );
if ( ++i >= argct )
return ToolMsg( PCCLIMSG_ARG_MISSING, --arg );
buffer = 1024 * GetInteger( *argList++ );
if ( convertError )
return ToolMsg( PCCLIMSG_BUF_SIZE, --arg, PCERROR_INVALID_PARAMETER );
break;
case INTERACTIVE:
if ( *(arg + 1) ) return ToolMsg( PCCLIMSG_SWITCH_UNKNOWN, --arg );
if ( inFile ) {
fclose( inFile );
ToolMsg( PCCLIMSG_CMD_FILE_CLOSED, inFileName );
}
if ( !LoadString( moduleUs, CLI_PROMPT, cmdPrompt, ENTRY_COUNT(cmdPrompt) ) )
_tcscpy( cmdPrompt, TEXT(">: ") );
inFile = NULL;
interact = TRUE;
return 0;
break;
case FILE_INPUT:
if ( *(arg + 1) ) return ToolMsg( PCCLIMSG_SWITCH_UNKNOWN, --arg );
if ( ++i >= argct )
return ToolMsg( PCCLIMSG_ARG_MISSING, --arg );
if ( inFile ) {
fclose( inFile );
ToolMsg( PCCLIMSG_CMD_FILE_CLOSED, inFileName );
}
_tcscpy( inFileName, *argList++);
inFile = _tfopen( inFileName, TEXT("rb") );
if ( !inFile )
return ToolMsg( PCCLIMSG_CMD_FILE_OPEN_FAIL, inFileName );
else {
char buf[1024];
TCHAR *opType;
int rdct = (int) fread( buf, sizeof(char), sizeof(buf), inFile );
if ( IsTextUnicode( buf, rdct, NULL ) ) opType = TEXT("rb");
else opType = TEXT("r");
fclose( inFile );
inFile = _tfopen( inFileName, opType );
if ( !inFile )
return ToolMsg( PCCLIMSG_CMD_FILE_OPEN_FAIL, inFileName );
}
ToolMsg( PCCLIMSG_CMD_FILE_OPEN_SUCCESS, inFileName );
interact = FALSE;
return 0;
break;
case ADMIN_DUMPREST:
if ( *(arg + 1) == TEXT('d') ) doDump = TRUE;
else if ( *(arg + 1) == TEXT('r') ) doRestore = TRUE;
else return ToolMsg( PCCLIMSG_ADMIN_OP_UNKNOWN, --arg );
if ( ++i >= argct )
return ToolMsg( PCCLIMSG_ARG_MISSING, --arg );
_tcscpy( adminFileName, *argList++);
adminFile = _tfopen( adminFileName, doDump? TEXT("wb") : TEXT("rb") );
if ( !adminFile )
return ToolMsg( doDump? PCCLIMSG_DUMP_FILE_OPEN_FAIL : PCCLIMSG_REST_FILE_OPEN_FAIL, adminFileName );
ToolMsg( doDump? PCCLIMSG_DUMP_FILE_OPEN_SUCCESS : PCCLIMSG_REST_FILE_OPEN_SUCCESS, adminFileName );
restIsData = TRUE;
dataObj = dataSubObj = DATA_DUMPREST;
opCode = doDump? TEXT(';') : TEXT(':');
break;
case OP_ADD:
case OP_REP:
case OP_DEL:
case OP_SWAP:
case OP_LIST:
case OP_UPDATE:
case OP_KILL: {
for ( int i = 1; *(arg + i); ++i ) {
if ( *(arg + i) == SUB_LIST ) getListData = TRUE;
else if ( *(arg + i) == SUB_FULLNAMES ) gShowFullNames = TRUE;
else return ToolMsg( PCCLIMSG_SWITCH_UNKNOWN, --arg );
}
if ( opCode != OP_LIST && opCode != swChar )
return ToolMsg( PCCLIMSG_OPERATION_CONFLICT, --arg );
opCode = swChar;
break;
}
case OP_COMMENT:
return 0;
break;
case OP_HELP:
case OP_HELP2:
if ( *(arg + 1) ) return ToolMsg( PCCLIMSG_SWITCH_UNKNOWN, --arg );
opCode = OP_HELP;
restIsData = TRUE;
break;
case DATA_GROUP:
dataObj = swChar;
sub = *(arg + 1);
if ( !sub ) sub = SUB_LIST;
else for ( int i = 2; *(arg + i); ++i ) {
if ( *(arg + i) == SUB_RUNNING ) listFlags |= PC_LIST_ONLY_RUNNING;
else if ( *(arg + i) == SUB_ONLY ) listFlags |= PC_LIST_MATCH_ONLY;
else if ( *(arg + i) == SUB_FULLNAMES ) gShowFullNames = TRUE;
else return ToolMsg( PCCLIMSG_SWITCH_SUFFIX_UNKNOWN, (void *) *(arg + i) );
}
if ( _tcschr( SUB_DefSummaryList, sub ) )
dataSubObj = sub;
else return ToolMsg( PCCLIMSG_SWITCH_UNKNOWN, --arg );
restIsData = TRUE;
break;
case DATA_PROC:
dataObj = swChar;
sub = *(arg + 1);
if ( !sub ) sub = SUB_LIST;
else for ( int i = 2; *(arg + i); ++i ) {
if ( *(arg + i) == SUB_RUNNING ) listFlags |= PC_LIST_ONLY_RUNNING;
else if ( *(arg + i) == SUB_ONLY ) listFlags |= PC_LIST_MATCH_ONLY;
else if ( *(arg + i) == SUB_FULLNAMES ) gShowFullNames = TRUE;
else return ToolMsg( PCCLIMSG_SWITCH_SUFFIX_UNKNOWN, (void *) *(arg + i) );
}
if ( _tcschr( SUB_DefSummaryList, sub ) )
dataSubObj = sub;
else return ToolMsg( PCCLIMSG_SWITCH_UNKNOWN, --arg );
restIsData = TRUE;
break;
case DATA_NAME:
dataObj = swChar;
if ( ++i < argct ) {
index = GetInteger( *argList++ );
if ( convertError )
return ToolMsg( PCCLIMSG_INVALID_ALIAS_INDEX, *--argList );
}
restIsData = TRUE;
break;
case DATA_SERVICE:
case DATA_MEDIATOR:
dataObj = swChar;
restIsData = TRUE;
break;
default:
return ToolMsg( PCCLIMSG_SWITCH_UNKNOWN, --arg );
break;
} // end switch
if ( restIsData ) {
pArgs = argList;
pArgCt = (argct > i) ? argct - i - 1 : 0;
break;
}
}
//-------------------------------------------------------------------------------------------//
// Short circuit remainder of processing if help requested...
if ( opCode == OP_HELP )
return ShowHelp( pArgs, pArgCt );
//-------------------------------------------------------------------------------------------//
// Perform correctness checks on supplied data...
if ( !dataObj )
return ToolMsg( PCCLIMSG_NO_OBJECT_NAME );
if ( opCode == OP_SWAP && dataObj != DATA_NAME )
return ToolMsg( PCCLIMSG_SWAP_NOT_ACCEPTABLE );
if ( dataObj != DATA_NAME && dataSubObj == SUB_SUMMARY && opCode != OP_LIST )
return ToolMsg( PCCLIMSG_SUMMARY_LIST_NOT_SPECIFIED, GetOpName(opCode) );
if ( dataObj != DATA_NAME && dataSubObj == SUB_LIST && opCode != OP_LIST && opCode != OP_KILL )
return ToolMsg( PCCLIMSG_LIST_LIST_NOT_SPECIFIED, GetOpName(opCode) );
if ( dataObj == DATA_NAME && opCode == OP_UPDATE )
return ToolMsg( PCCLIMSG_ALIAS_VERB_CONFLICT, GetOpName(opCode) );
if ( dataObj == DATA_SERVICE && opCode != OP_LIST && opCode != OP_REP )
return ToolMsg( PCCLIMSG_CONTROL_VERB_CONFLICT, GetOpName(opCode) );
if ( dataObj == DATA_MEDIATOR && opCode != OP_LIST )
return ToolMsg( PCCLIMSG_MEDIATOR_VERB_CONFLICT, GetOpName(opCode) );
//-------------------------------------------------------------------------------------------//
// Connect to the target and quit if fails, else give action description...
if ( _tcscmp( target, oldTarget ) || buffer != oldBuffer ) {
if ( *oldTarget ) PCClose( targId );
ToolMsg( PCCLIMSG_CONNECTING, target, ERROR_SUCCESS, IntToPtr(buffer), IntToPtr(buffer) );
targId = PCOpen( target, NULL, buffer );
if ( !targId ) {
*oldTarget = 0;
oldBuffer = 0;
return ToolMsg( PCCLIMSG_CONNECT_FAILED, target, PCGetLastError( targId ) );
}
ToolMsg( PCCLIMSG_CONNECT_SUCCESS, target );
_tcscpy( oldTarget, target );
oldBuffer = buffer;
if ( PCGetServiceInfo( targId, &sysInfo, sizeof(sysInfo) ) )
ShowSysInfo( sysInfo );
else
ToolMsg( PCCLIMSG_SERVICE_QUERY_FAILED, target, PCGetLastError( targId ) );
}
if ( dataObj == DATA_NAME )
ToolMsg( PCCLIMSG_PERFORMING_ALIAS_OP, GetOpName(opCode), ERROR_SUCCESS,
GetDataName(dataObj, dataSubObj), IntToPtr(index) );
else if ( dataObj == DATA_MEDIATOR )
ToolMsg( PCCLIMSG_PERFORMING_MEDIATOR_OP, pArgCt? *pArgs : TEXT("???") );
else if ( dataObj != DATA_DUMPREST )
ToolMsg( PCCLIMSG_PERFORMING_OTHER_OP, GetOpName(opCode), ERROR_SUCCESS,
GetDataName(dataObj, dataSubObj) );
//-------------------------------------------------------------------------------------------//
// Prepare and perform the requested action...
BOOL rc;
if ( !sepChar ) {
TCHAR sepCharBuf[256];
if ( !LoadString( moduleUs, COLHEAD_SEPARATOR_CHAR, sepCharBuf, ENTRY_COUNT(sepCharBuf) ) )
sepChar = TEXT('-');
else sepChar = sepCharBuf[0];
}
switch ( dataObj ) {
case DATA_GROUP: {
if ( dataSubObj == SUB_DEFS ) {
PCJobSummary grpSummaryEntry;
TCHAR detail[2000], detail2[2000]; // space for detail with variable data too
PCJobDetail *grpDetail = (PCJobDetail *) detail;
grpDetail->vLength = sizeof(detail) - offsetof( PCJobDetail, vLength );
BuildGrpDetail( *grpDetail, pArgs, pArgCt );
if ( !convertError ) switch ( opCode ) {
case OP_REP:
case OP_UPDATE:
memcpy( detail2, detail, sizeof (PCProcDetail) );
if ( PCGetJobDetail( targId, (PCJobDetail *) detail2, sizeof(detail2), &updateCtr ) ) {
if ( opCode == OP_UPDATE ) MergeGroupDetail( *grpDetail, (PCJobDetail &) detail2 );
rc = PCReplJobDetail( targId, grpDetail, updateCtr, getListData? &grpSummaryEntry : NULL );
if ( rc && getListData ) ShowGrpSummary( &grpSummaryEntry, 1 );
}
break;
case OP_ADD:
rc = PCAddJobDetail( targId, grpDetail, getListData? &grpSummaryEntry : NULL );
if ( rc && getListData ) ShowGrpSummary( &grpSummaryEntry, 1 );
break;
case OP_DEL:
PCDeleteJobDetail( targId, grpDetail );
break;
case OP_LIST:
grpDetail->vLength = sizeof(detail) - offsetof( PCJobDetail, vLength );
if ( PCGetJobDetail( targId, grpDetail, sizeof(detail), &updateCtr ) )
ShowGrpDetail( *grpDetail );
break;
} // end switch op code within group data
break;
}
else if ( dataSubObj == SUB_SUMMARY ) {
PCUINT32 totCount = 0, entryCount = buffer / sizeof(PCJobSummary);
PCJobSummary *grpSummary = new PCJobSummary[entryCount];
if ( !grpSummary )
return ToolMsg( PCCLIMSG_NOT_ENOUGH_MEMORY );
BuildGrpSummary( *grpSummary, pArgs, pArgCt, &listFlags );
if ( !convertError ) for ( BOOL moreData = TRUE, isFirst = TRUE; moreData; isFirst = FALSE ) {
PCINT32 count = PCGetJobSummary( targId, grpSummary, entryCount * sizeof(PCJobSummary), listFlags );
moreData = PCGetLastError( targId ) == PCERROR_MORE_DATA;
totCount += count;
if ( count >= 0 ) ShowGrpSummary( grpSummary, count, isFirst, moreData? -1 : totCount );
if ( count > 0 ) _tcsncpy( grpSummary[0].jobName, grpSummary[count - 1].jobName, JOB_NAME_LEN );
}
delete [] grpSummary;
}
// Not an operation on definition or summary so is either kill or list...
else {
if ( opCode == OP_KILL ) {
JOB_NAME groupName;
memset( groupName, 0, sizeof(groupName) );
if ( pArgCt ) _tcsncpy( groupName, *pArgs, JOB_NAME_LEN );
PCKillJob( targId, groupName );
}
// Must be list...
else {
PCUINT32 totCount = 0, entryCount = buffer / sizeof(PCJobListItem);
PCJobListItem *grpListItem = new PCJobListItem[entryCount];
if ( !grpListItem )
return ToolMsg( PCCLIMSG_NOT_ENOUGH_MEMORY );
BuildGrpListItem( *grpListItem, pArgs, pArgCt, &listFlags );
if ( !convertError ) for ( BOOL moreData = TRUE, isFirst = TRUE; moreData; isFirst = FALSE ) {
PCINT32 count = PCGetJobList( targId, grpListItem, entryCount * sizeof(PCJobListItem), listFlags );
moreData = PCGetLastError( targId ) == PCERROR_MORE_DATA;
totCount += count;
if ( count >= 0 ) ShowGrpList( grpListItem, count, isFirst, moreData? -1 : totCount );
if ( count > 0 ) _tcsncpy( grpListItem[0].jobName, grpListItem[--count].jobName, JOB_NAME_LEN );
}
delete [] grpListItem;
}
}
break;
}
//-------------------------------------------------------------------------------------------//
case DATA_PROC: {
if ( dataSubObj == SUB_DEFS ) {
PCProcSummary procSummaryEntry;
TCHAR detail[2000], detail2[2000]; // space for detail with variable data too
PCProcDetail *procDetail = (PCProcDetail *) detail;
procDetail->vLength = sizeof(detail) - offsetof( PCProcDetail, vLength );
BuildProcDetail( *procDetail, pArgs, pArgCt );
if ( !convertError ) switch ( opCode ) {
case OP_REP:
case OP_UPDATE:
memcpy( detail2, detail, sizeof (PCProcDetail) );
if ( PCGetProcDetail( targId, (PCProcDetail *) detail2, sizeof(detail2), &updateCtr ) ) {
if ( opCode == OP_UPDATE ) MergeProcDetail( *procDetail, (PCProcDetail &) detail2 );
BOOL rc = PCReplProcDetail( targId, procDetail, updateCtr, getListData? &procSummaryEntry : NULL );
if ( rc && getListData )
ShowProcSummary( &procSummaryEntry, 1 );
}
break;
case OP_ADD:
if ( getListData )
ShowProcSummary( &procSummaryEntry, PCAddProcDetail( targId, procDetail, &procSummaryEntry ) );
else
PCAddProcDetail( targId, procDetail );
break;
case OP_DEL:
PCDeleteProcDetail( targId, procDetail );
break;
case OP_LIST:
procDetail->vLength = sizeof(detail) - offsetof( PCProcDetail, vLength );
if ( PCGetProcDetail( targId, procDetail, sizeof(detail), &updateCtr ) )
ShowProcDetail( *procDetail );
break;
} // end switch op code within proc data
break;
}
else if ( dataSubObj == SUB_SUMMARY ) {
PCUINT32 totCount = 0, entryCount = buffer / sizeof(PCProcSummary);
PCProcSummary *procSummary = new PCProcSummary[entryCount];
if ( !procSummary )
return ToolMsg( PCCLIMSG_NOT_ENOUGH_MEMORY );
BuildProcSummary( *procSummary, pArgs, pArgCt, &listFlags );
if ( !convertError ) for ( BOOL moreData = TRUE, isFirst = TRUE; moreData; isFirst = FALSE ) {
PCINT32 count = PCGetProcSummary( targId, procSummary, entryCount * sizeof(PCProcSummary), listFlags );
moreData = PCGetLastError( targId ) == PCERROR_MORE_DATA;
totCount += count;
if ( count >= 0 ) ShowProcSummary( procSummary, count, isFirst, moreData? -1 : totCount );
if ( count > 0 ) _tcsncpy( procSummary[0].procName, procSummary[--count].procName, PROC_NAME_LEN );
}
delete [] procSummary;
}
else {
if ( opCode == OP_KILL ) {
PID_VALUE pid = 0;
TIME_VALUE create = 0x777deadfeeb1e777;
if ( pArgCt > 0 ) pid = GetUInteger64( *pArgs++ );
if ( pArgCt > 1 ) create = GetInteger64( *pArgs );
if ( !convertError )
PCKillProcess( targId, pid, create );
}
else {
PCUINT32 totCount = 0, entryCount = buffer / sizeof(PCProcListItem);
PCProcListItem *procListItem = new PCProcListItem[entryCount];
if ( !procListItem )
return ToolMsg( PCCLIMSG_NOT_ENOUGH_MEMORY );
BuildProcListItem( *procListItem, pArgs, pArgCt, &listFlags );
if ( !convertError ) for ( BOOL moreData = TRUE, isFirst = TRUE; moreData; isFirst = FALSE ) {
PCINT32 count = PCGetProcList( targId, procListItem, entryCount * sizeof(PCProcListItem), listFlags );
moreData = PCGetLastError( targId ) == PCERROR_MORE_DATA;
totCount += count;
if ( count >= 0 ) ShowProcList( procListItem, count, isFirst, moreData? -1 : totCount );
if ( count > 0 ) {
_tcsncpy( procListItem[0].procName, procListItem[--count].procName, PROC_NAME_LEN );
procListItem[0].procStats.pid = procListItem[count].procStats.pid;
}
}
delete [] procListItem;
}
}
break;
}
//-------------------------------------------------------------------------------------------//
case DATA_NAME:
// Prime update counter and get buffer full of names, then execute verb...
numRules = PCGetNameRules( targId, nameRules, sizeof(nameRules),
opCode == OP_LIST? index : 0, &updateCtr );
switch ( opCode ) {
case OP_ADD:
case OP_REP: {
PCNameRule newRule;
BuildNameRule( newRule, pArgs, pArgCt );
if ( convertError ) break;
if ( getListData ) {
numRules = (opCode == OP_ADD)?
PCAddNameRule( targId, &newRule, index, updateCtr, nameRules, sizeof(nameRules), 0 ) :
PCReplNameRule( targId, &newRule, index, updateCtr, nameRules, sizeof(nameRules), 0 );
ShowNameRules( nameRules, numRules );
}
else
numRules = (opCode == OP_ADD)?
PCAddNameRule( targId, &newRule, index, updateCtr ) :
PCReplNameRule( targId, &newRule, index, updateCtr );
break;
}
case OP_DEL:
if ( getListData ) {
numRules = PCDeleteNameRule( targId, index, updateCtr, nameRules, sizeof(nameRules), 0 );
ShowNameRules( nameRules, numRules );
}
else
PCDeleteNameRule( targId, index, updateCtr );
break;
case OP_LIST:
ShowNameRules( nameRules, numRules, index );
break;
case OP_SWAP:
if ( getListData ) {
numRules = PCSwapNameRules( targId, index, updateCtr, nameRules, sizeof(nameRules), 0 );
ShowNameRules( nameRules, numRules );
}
else
PCSwapNameRules( targId, index, updateCtr );
break;
} // end switch op code for data names
break;
//-------------------------------------------------------------------------------------------//
case DATA_SERVICE:
switch ( opCode ) {
case OP_REP:
PCSystemParms sysParms;
BuildSystemParms( sysParms, pArgs, pArgCt );
if ( !convertError )
PCSetServiceParms( targId, &sysParms, sizeof(sysInfo) );
break;
case OP_LIST:
if ( PCGetServiceInfo( targId, &sysInfo, sizeof(sysInfo) ) )
ShowSysInfo( sysInfo, FALSE );
break;
} // end switch op code for data names
break;
//-------------------------------------------------------------------------------------------//
case DATA_MEDIATOR:
DoMediatorControl( pArgs, pArgCt );
break;
//-------------------------------------------------------------------------------------------//
case DATA_DUMPREST: // Perform complete dump or restore of data base
int err = DoDumpRestore( adminFile, doDump ); // file already open
fflush( adminFile ); // flush data
if ( !err && ferror( adminFile ) )
err = cFileError( doDump ); // show stream was errored out
fclose( adminFile ); // done with file
if ( err ) {
ToolMsg( PCCLIMSG_DUMP_RESTORE_FAILED );
return err;
}
break;
} // end switch data obj
PCINT32 err = convertError? PCERROR_INVALID_PARAMETER : PCGetLastError( targId );
if ( err )
ToolMsg( PCCLIMSG_REQUEST_FAILED, NULL, err );
else
ToolMsg( PCCLIMSG_REQUEST_SUCCESSFUL );
return err;
}
//-------------------------------------------------------------------------------------------//
static void DoMediatorControl( TCHAR **pArgs, PCUINT32 pArgCt ) {
PCINT32 ctlCmd = PCCFLAG_SIGNATURE;
if ( pArgCt > 0 ) {
if ( !_tcsicmp( *pArgs, TEXT("stop") ) ) ctlCmd |= PCCFLAG_STOP_MEDIATOR; // do not localize
else if ( !_tcsicmp( *pArgs, TEXT("start") ) ) ctlCmd |= PCCFLAG_START_MEDIATOR; // do not localize
else if ( _tcsicmp( *pArgs, TEXT("restart") ) ) { // do not localize
ToolMsg( PCCLIMSG_MEDIATOR_ACTION_UNKNOWN, *pArgs );
return;
}
}
else {
ToolMsg( PCCLIMSG_MEDIATOR_ACTION_MISSING );
return;
}
if ( pArgCt > 1 )
ToolMsg( PCCLIMSG_MEDIATOR_ACTION_IGNORED, *pArgs );
if ( !_tcsicmp( *pArgs, TEXT("restart") ) ) {
if ( !PCControlFunction( targId, ctlCmd | PCCFLAG_STOP_MEDIATOR ) )
ToolMsg( PCCLIMSG_MEDIATOR_CONTROL_ERROR, NULL, PCGetLastError( targId ) );
else {
Sleep( 100 );
if ( !PCControlFunction( targId, ctlCmd | PCCFLAG_START_MEDIATOR ) )
ToolMsg( PCCLIMSG_MEDIATOR_CONTROL_ERROR, NULL, PCGetLastError( targId ) );
}
}
else if ( !PCControlFunction( targId, ctlCmd ) )
ToolMsg( PCCLIMSG_MEDIATOR_CONTROL_ERROR, NULL, PCGetLastError( targId ) );
}
//-------------------------------------------------------------------------------------------//
static void DispDumpComment( FILE *adminFile, PCULONG32 msgID, PCINT32 count ) {
TCHAR *fileCmnt;
if ( !FormatMessage( FORMAT_MESSAGE_FROM_HMODULE + FORMAT_MESSAGE_ARGUMENT_ARRAY +
FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, msgID, 0, (TCHAR *) &fileCmnt, 0, (char **) &count ) )
_ftprintf( adminFile, TEXT("-%c <message formatting failed>...\n"), OP_COMMENT );
else {
_ftprintf( adminFile, TEXT("-%c%s"), OP_COMMENT, fileCmnt );
LocalFree( fileCmnt );
}
}
static int cFileError( BOOL dump ) {
_tperror( dump? TEXT("dump file error") : TEXT("restore file error") );
return PCCLIMSG_REQUEST_FAILED;
}
static int DoDumpRestore( FILE *adminFile, BOOL dump ) {
PCNameRule nameRules[100];
PCProcSummary procRules[100];
PCJobSummary grpRules[100];
char detail[8192]; // detail buffer
// Dump operation...
if ( dump ) {
// Dump process alias rules...
DispDumpComment( adminFile, PCCLIMSG_DUMPCOMMENT_BEGIN_ALIASES );
BOOL moreRules = TRUE;
PCINT32 totalRules = 0;
for ( PCINT32 index = 0, numRules; moreRules; index += numRules ) {
numRules = PCGetNameRules( targId, nameRules, sizeof(nameRules), index );
if ( numRules < 0 ) return PCGetLastError( targId );
moreRules = PCGetLastError( targId ) == PCERROR_MORE_DATA;
totalRules += numRules;
for ( PCINT32 i = 0; i < (moreRules? numRules : numRules - 1); ++i ) {
_ftprintf( adminFile, TEXT(" -%c -%c %ld %c \"%s\" \"%s\" \"%s\"\n"),
OP_ADD, DATA_NAME, index + i,
nameRules[i].matchType, nameRules[i].matchString,
nameRules[i].procName, nameRules[i].description );
}
}
DispDumpComment( adminFile, PCCLIMSG_DUMPCOMMENT_END_ALIASES, totalRules - 1 );
if ( ferror( adminFile ) ) return cFileError( dump ); // see if stream was errored out
// Dump group rules...
DispDumpComment( adminFile, PCCLIMSG_DUMPCOMMENT_BEGIN_GROUPS );
moreRules = TRUE;
totalRules = 0;
memset( grpRules, 0, sizeof(grpRules) );
PCJobDetail *grpDet = (PCJobDetail *) detail;
while ( moreRules ) {
memcpy( &grpRules[0], &grpRules[ENTRY_COUNT(grpRules) - 1], sizeof(grpRules[0]) );
numRules = PCGetJobSummary( targId, grpRules, sizeof(grpRules) );
if ( numRules < 0 ) return PCGetLastError( targId );
totalRules += numRules;
moreRules = PCGetLastError( targId ) == PCERROR_MORE_DATA;
for ( PCINT32 i = 0; i < numRules; ++i ) {
memcpy( grpDet, &grpRules[i], sizeof(grpRules[i] ) );
if ( PCGetJobDetail( targId, grpDet, sizeof(detail) ) ) {
_ftprintf( adminFile, TEXT(" -%c -%c%c \"%s\""),
OP_ADD, DATA_GROUP, SUB_DEFS, grpDet->base.jobName );
DumpMgmtParms( grpDet->base.mgmtParms, grpDet->vLength, grpDet->vData );
}
else return PCGetLastError( targId );
}
}
DispDumpComment( adminFile, PCCLIMSG_DUMPCOMMENT_END_GROUPS, totalRules );
if ( ferror( adminFile ) ) return cFileError( dump ); // see if stream was errored out
// Dump process rules...
DispDumpComment( adminFile, PCCLIMSG_DUMPCOMMENT_BEGIN_PROCESSES );
moreRules = TRUE;
totalRules = 0;
memset( procRules, 0, sizeof(procRules) );
PCProcDetail *procDet = (PCProcDetail *) detail;
while ( moreRules ) {
memcpy( &procRules[0], &procRules[ENTRY_COUNT(procRules) - 1], sizeof(procRules[0]) );
numRules = PCGetProcSummary( targId, procRules, sizeof(procRules) );
if ( numRules < 0 ) return PCGetLastError( targId );
totalRules += numRules;
moreRules = PCGetLastError( targId ) == PCERROR_MORE_DATA;
for ( PCINT32 i = 0; i < numRules; ++i ) {
memcpy( procDet, &procRules[i], sizeof(procRules[i] ) );
if ( PCGetProcDetail( targId, procDet, sizeof(detail) ) ) {
_ftprintf( adminFile, TEXT(" -%c -%c%c \"%s\""),
OP_ADD, DATA_PROC, SUB_DEFS, procDet->base.procName );
if ( *procDet->base.memberOfJobName )
_ftprintf( adminFile, TEXT(" -%c \"%s\""), DATA_GROUP, procDet->base.memberOfJobName );
DumpMgmtParms( procDet->base.mgmtParms, procDet->vLength, procDet->vData );
}
else return PCGetLastError( targId );
}
}
DispDumpComment( adminFile, PCCLIMSG_DUMPCOMMENT_END_PROCESSES, totalRules );
if ( ferror( adminFile ) ) return cFileError( dump ); // see if stream was errored out
}
else {
int argct;
BOOL haveCmd;
TCHAR *cmdLine;
PCINT32 ctlCmd = PCCFLAG_SIGNATURE +
PCCFLAG_DELALL_NAME_RULES + PCCFLAG_DELALL_PROC_DEFS + PCCFLAG_DELALL_JOB_DEFS;
if ( !PCControlFunction( targId, ctlCmd ) )
return ToolMsg( PCCLIMSG_RESTORE_CLEAR_ERROR, NULL, PCGetLastError( targId ) );
else {
BOOL saveInteract = interact;
interact = FALSE;
int retCode;
for ( haveCmd = GetNextCommand( adminFile, &cmdLine );
haveCmd;
haveCmd = GetNextCommand( adminFile, &cmdLine ) ) {
if ( ferror( adminFile ) ) return cFileError( dump );
TCHAR **argList = CommandLineToArgvW( cmdLine, &argct );
if ( !**argList ) retCode = DoCommands( argct - 1, argList + 1 );
else retCode = DoCommands( argct, argList );
GlobalFree( argList );
}
interact = saveInteract;
}
}
return ERROR_SUCCESS;
}
static void DumpMgmtParms( MGMT_PARMS &mgt, PCINT16 len, TCHAR *data ) {
TCHAR flags[16];
ShowMgmtFlags( flags, mgt.mFlags, TRUE );
if ( *flags )
_ftprintf( adminFile, TEXT(" -%c %s"), DEF_FLAGS, flags );
if ( mgt.affinity )
_ftprintf( adminFile, TEXT(" -%c 0x%I64x"), DEF_AFF, mgt.affinity );
if ( mgt.priority )
_ftprintf( adminFile, TEXT(" -%c %c"), DEF_PRIO, ShowPriority( mgt.priority ) );
if ( mgt.minWS || mgt.maxWS )
_ftprintf( adminFile, TEXT(" -%c %I64u %I64u"), DEF_WS, mgt.minWS / 1024, mgt.maxWS / 1024 );
if ( mgt.schedClass )
_ftprintf( adminFile, TEXT(" -%c %lu"), DEF_SCHED, mgt.schedClass );
if ( mgt.jobMemoryLimit )
_ftprintf( adminFile, TEXT(" -%c %I64u"), DEF_GROUPMEM, mgt.jobMemoryLimit / 1024 );
if ( mgt.procMemoryLimit )
_ftprintf( adminFile, TEXT(" -%c %I64u"), DEF_PROCMEM, mgt.procMemoryLimit / 1024 );
if ( mgt.jobTimeLimitCNS )
_ftprintf( adminFile, TEXT(" -%c %I64u"), DEF_GROUPTIME, mgt.jobTimeLimitCNS / 10000 );
if ( mgt.procTimeLimitCNS )
_ftprintf( adminFile, TEXT(" -%c %I64u"), DEF_PROCTIME, mgt.procTimeLimitCNS / 10000 );
if ( mgt.procCountLimit )
_ftprintf( adminFile, TEXT(" -%c %lu"), DEF_PROCCOUNT, mgt.procCountLimit );
if ( *mgt.description )
_ftprintf( adminFile, TEXT(" -%c \"%s\""), DEF_DESC, mgt.description );
if ( len )
_ftprintf( adminFile, TEXT(" -%c \"%*s\""), DEF_VARDATA, len / sizeof(TCHAR) - 1, data );
_ftprintf( adminFile, TEXT("\n") );
}
static void InsertTableData( PCTableDef *table, PCULONG32 index, TCHAR *dataItem, BOOL printIt ) {
PCULONG32 leftSkip = 0, dataLen = min( _tcslen( dataItem ), colWidth[index] );
switch ( table[index].justification ) {
case PCCOL_JUST_RIGHT: leftSkip = colWidth[index] - dataLen; break;
case PCCOL_JUST_LEFT: leftSkip = 0; break;
case PCCOL_JUST_CENTER: leftSkip = (colWidth[index] - dataLen) / 2; break;
}
_tcsncpy( rowData + colOffset[index] + leftSkip, dataItem, dataLen );
if ( printIt ) {
rowData[tableWidth] = 0;
PrintLine( rowData, 1 );
}
}
static void BuildTableHeader( PCTableDef *table, PCULONG32 entries, BOOL printIt ) {
PCULONG32 leftSkip = 0, widthCol, widthHead, offset = 0;
wmemset( colHead, SPACE, ENTRY_COUNT(colHead) );
wmemset( colDash, SPACE, ENTRY_COUNT(colDash) );
for ( PCULONG32 i = 0; i < entries; ++i ) {
TCHAR head[512];
if ( !LoadString( moduleUs,
gShowFullNames? table[i].longStringID : table[i].shortStringID,
head, ENTRY_COUNT(head) )
)
_tcscpy( head, TEXT("(load-fail)") );
widthHead = (PCULONG32) _tcslen( head );
widthCol = max( widthHead, gShowFullNames? table[i].longMinLen : table[i].shortMinLen );
switch ( table[i].justification ) {
case PCCOL_JUST_RIGHT: leftSkip = widthCol - widthHead; break;
case PCCOL_JUST_LEFT: leftSkip = 0; break;
case PCCOL_JUST_CENTER: leftSkip = (widthCol - widthHead) / 2; break;
}
_tcsncpy( colHead + offset + leftSkip, head, widthHead );
_tcsnset( colDash + offset, sepChar, widthCol );
colWidth[i] = widthCol;
colOffset[i] = offset;
offset += widthCol + 1;
}
tableWidth = offset;
colHead[tableWidth] = 0;
colDash[tableWidth] = 0;
if ( printIt ) {
PrintLine( colHead, 1 );
PrintLine( colDash, 1 );
}
}
static void ShowNameRules( PCNameRule *rule, PCINT32 count, PCINT32 index ) {
static PCTableDef aliasTable[] = {
{ COLHEAD_ALIAS_RULE_NUMBER, COLHEAD_ALIAS_RULE_NUMBER, 4, 4, PCCOL_JUST_RIGHT, TEXT("%ld") },
{ COLHEAD_ALIAS_MATCH_TYPE, COLHEAD_ALIAS_MATCH_TYPE, 10, 10, PCCOL_JUST_CENTER, TEXT("%c") },
{ COLHEAD_ALIAS_MATCH_DATA_LONG, COLHEAD_ALIAS_MATCH_DATA_SHORT, MATCH_STRING_LEN, 24, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_ALIAS_NAME_LONG, COLHEAD_ALIAS_NAME_SHORT, PROC_NAME_LEN, 21, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_ALIAS_DESCRIPTION_LONG,COLHEAD_ALIAS_DESCRIPTION_SHORT, NAME_DESCRIPTION_LEN, 55, PCCOL_JUST_LEFT, TEXT("%s") }
};
if ( count < 0 ) return;
// Build and display table headers (and set global table parameters)...
BuildTableHeader( aliasTable, ENTRY_COUNT(aliasTable) );
// Build and display each data row...
PCINT32 TotRules = 0;
for ( ;; ) {
TotRules += count;
for ( PCINT32 i = 0; i < count; ++i, ++rule ) {
wmemset( rowData, SPACE, ENTRY_COUNT(rowData) );
// Insert each data item into row...
for ( PCINT32 j = 0; j < ENTRY_COUNT(aliasTable); ++j ) {
TCHAR dataItem[256];
// Get formatted data...
switch ( j ) {
case 0: _stprintf( dataItem, aliasTable[j].rowFmt, index + i ); break;
case 1: _stprintf( dataItem, aliasTable[j].rowFmt, rule->matchType ); break;
case 2: _stprintf( dataItem, aliasTable[j].rowFmt, rule->matchString ); break;
case 3: _stprintf( dataItem, aliasTable[j].rowFmt, rule->procName ); break;
case 4: _stprintf( dataItem, aliasTable[j].rowFmt, rule->description ); break;
}
// Insert data into row, print if last item...
InsertTableData( aliasTable, j, dataItem, j == ENTRY_COUNT(aliasTable) - 1 );
}
}
if ( PCGetLastError( targId ) == PCERROR_MORE_DATA ) {
index += count;
rule = nameRules;
count = PCGetNameRules( targId, nameRules, sizeof(nameRules), index );
}
else break;
}
// Display table suffix...
PrintLine( colDash, 1 );
PrintHelp( HELP_ALIAS, FALSE );
// Show count of rules retrieved...
ToolMsg( PCCLIMSG_RETRIEVED_ALIAS_RULES_LIST, TotRules );
}
static TCHAR *GetOpName( TCHAR code ) {
static TCHAR result[128];
static struct { TCHAR op; PCULONG32 strID; } opNames[] = {
{ OP_ADD, VERB_NAME_ADD },
{ OP_REP, VERB_NAME_REPLACE },
{ OP_DEL, VERB_NAME_DELETE },
{ OP_SWAP, VERB_NAME_SWAP },
{ OP_LIST, VERB_NAME_LIST },
{ OP_UPDATE, VERB_NAME_UPDATE },
{ OP_KILL, VERB_NAME_KILL },
{ TEXT(';'), VERB_NAME_DUMP },
{ TEXT(':'), VERB_NAME_RESTORE },
};
for ( PCUINT32 i = 0; i < ENTRY_COUNT(opNames) && code != opNames[i].op; ++i ) ;
if ( i >= ENTRY_COUNT(opNames) || !LoadString( moduleUs, opNames[i].strID, result, ENTRY_COUNT(result) ) )
_tcscpy( result, TEXT("<err>") );
return result;
}
static TCHAR *GetDataName( TCHAR code, TCHAR subCode ) {
static TCHAR result[128];
static struct { TCHAR op; PCULONG32 strID; } dNames[] = {
{ DATA_NAME, DATA_NAME_ALIAS },
{ DATA_GROUP, DATA_NAME_GROUP },
{ DATA_PROC, DATA_NAME_PROCESS },
{ DATA_SERVICE, DATA_NAME_VERSION },
{ DATA_MEDIATOR,DATA_NAME_MEDIATOR },
{ TEXT(';'), DATA_NAME_PROCCON },
};
for ( PCUINT32 i = 0; i < ENTRY_COUNT(dNames) && code != dNames[i].op; ++i ) ;
if ( i >= ENTRY_COUNT(dNames) || !LoadString( moduleUs, dNames[i].strID, result, ENTRY_COUNT(result) ) )
_tcscpy( result, TEXT("<err>") );
else {
_tcscat( result, TEXT(" ") );
_tcscat( result, GetDataSubName( subCode ) );
}
return result;
}
static TCHAR *GetDataSubName( TCHAR code ) {
static TCHAR result[128];
static struct { TCHAR op; PCULONG32 strID; } sNames[] = {
{ SUB_DEFS, SUBDATA_NAME_DEFINITION },
{ SUB_SUMMARY, SUBDATA_NAME_SUMMARY },
{ SUB_LIST, SUBDATA_NAME_LIST },
{ TEXT(';'), SUBDATA_NAME_PROCCON_DATA },
};
for ( PCUINT32 i = 0; i < ENTRY_COUNT(sNames) && code != sNames[i].op; ++i ) ;
if ( i >= ENTRY_COUNT(sNames) )
_tcscpy( result, TEXT("") );
else if ( !LoadString( moduleUs, sNames[i].strID, result, ENTRY_COUNT(result) ) )
_tcscpy( result, TEXT("<err>") );
return result;
}
static void ShowListFlags( PC_LIST_FLAGS flags, TCHAR out[8] ) {
for ( PCUINT32 i = 0; i < 6; ++i ) out[i] = TEXT('.');
out[6] = 0;
if ( flags & PCLFLAG_IS_RUNNING ) out[0] = TEXT('R');
if ( flags & PCLFLAG_IS_DEFINED ) out[1] = TEXT('D');
if ( flags & PCLFLAG_IS_MANAGED ) out[2] = TEXT('M');
if ( flags & PCLFLAG_HAS_NAME_RULE ) out[3] = TEXT('N');
if ( flags & PCLFLAG_HAS_MEMBER_OF_JOB ) out[4] = TEXT('G');
if ( flags & PCLFLAG_IS_IN_A_JOB ) out[5] = TEXT('I');
}
static void FormatTime( TCHAR *str, int strLen, TIME_VALUE time )
{
SYSTEMTIME systime, localsystime;
if ( FileTimeToSystemTime( (FILETIME *) &time, &systime ) &&
SystemTimeToTzSpecificLocalTime( NULL, &systime, &localsystime ) ) {
int len = GetDateFormat( LOCALE_USER_DEFAULT, 0, &localsystime, NULL, str, strLen - 1 );
if ( len ) {
str[len - 1 ] = SPACE;
GetTimeFormat( LOCALE_USER_DEFAULT, 0, &localsystime, NULL, &str[len], strLen - len - 1);
}
}
else
str[0] = 0;
}
static void ShowProcList( PCProcListItem *list, PCINT32 count, BOOL isFirst, int totcnt ) {
static PCTableDef procTable[] = {
{ COLHEAD_PROCLIST_FLAGS, COLHEAD_PROCLIST_FLAGS, 6, 6, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_PROCLIST_PID, COLHEAD_PROCLIST_PID, 5, 5, PCCOL_JUST_RIGHT, TEXT("%.0I64u") },
{ COLHEAD_PROCLIST_PROCESS_ALIAS_LONG, COLHEAD_PROCLIST_PROCESS_ALIAS_SHORT, PROC_NAME_LEN, 20, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_PROCLIST_IMAGE_NAME_LONG, COLHEAD_PROCLIST_IMAGE_NAME_SHORT, IMAGE_NAME_LEN, 16, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_PROCLIST_MEMBER_OF_GROUP_LONG,COLHEAD_PROCLIST_MEMBER_OF_GROUP_SHORT, JOB_NAME_LEN, 16, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_PROCLIST_PRIORITY, COLHEAD_PROCLIST_PRIORITY, 3, 3, PCCOL_JUST_CENTER,TEXT("%c") },
{ COLHEAD_PROCLIST_AFFINITY, COLHEAD_PROCLIST_AFFINITY, 18, 18, PCCOL_JUST_CENTER,TEXT("0x%016I64x") },
{ COLHEAD_PROCLIST_USER_TIME, COLHEAD_PROCLIST_USER_TIME, 9, 9, PCCOL_JUST_RIGHT, TEXT("%I64d") },
{ COLHEAD_PROCLIST_KERNEL_TIME, COLHEAD_PROCLIST_KERNEL_TIME, 9, 9, PCCOL_JUST_RIGHT, TEXT("%I64d") },
{ COLHEAD_PROCLIST_CREATE_TIME, COLHEAD_PROCLIST_CREATE_TIME, 23, 23, PCCOL_JUST_LEFT, TEXT("%s") },
};
if ( count < 0 ) return;
if ( isFirst )
BuildTableHeader( procTable, ENTRY_COUNT(procTable) );
TCHAR flags[8], fmtCreateTime[512];
for ( PCINT32 i = 0; i < count; ++i, ++list ) {
wmemset( rowData, SPACE, ENTRY_COUNT(rowData) );
if ( gShowFmtProcTime && list->procStats.createTime )
FormatTime( fmtCreateTime, ENTRY_COUNT(fmtCreateTime), list->procStats.createTime );
else if ( list->procStats.createTime )
_stprintf( fmtCreateTime, TEXT("%I64d"), list->procStats.createTime );
else
_stprintf( fmtCreateTime, TEXT(" ") );
ShowListFlags( list->lFlags, flags );
// Insert each data item into row...
PCINT32 lastRow = (list->lFlags & PCLFLAG_IS_RUNNING) ? ENTRY_COUNT(procTable) : 3;
for ( PCINT32 j = 0; j < lastRow; ++j ) {
TCHAR dataItem[256];
// Get formatted data...
switch ( j ) {
case 0: _stprintf( dataItem, procTable[j].rowFmt, flags ); break;
case 1: _stprintf( dataItem, procTable[j].rowFmt, list->procStats.pid ); break;
case 2: _stprintf( dataItem, procTable[j].rowFmt, list->procName ); break;
case 3: _stprintf( dataItem, procTable[j].rowFmt, list->imageName ); break;
case 4: _stprintf( dataItem, procTable[j].rowFmt, list->jobName ); break;
case 5: _stprintf( dataItem, procTable[j].rowFmt, ShowPriority( list->actualPriority ) ); break;
case 6: _stprintf( dataItem, procTable[j].rowFmt, list->actualAffinity ); break;
case 7: _stprintf( dataItem, procTable[j].rowFmt, list->procStats.TotalUserTime / 10000 ); break;
case 8: _stprintf( dataItem, procTable[j].rowFmt, list->procStats.TotalKernelTime / 10000 ); break;
case 9: _stprintf( dataItem, procTable[j].rowFmt, fmtCreateTime ); break;
}
// Insert data into row, print if last item...
InsertTableData( procTable, j, dataItem, j == lastRow - 1 );
}
}
// Display table suffix...
if ( totcnt >= 0 ) {
PrintLine( colDash, 1 );
PrintHelp( HELP_LIST, FALSE );
ToolMsg( PCCLIMSG_RETRIEVED_PROCESS_LIST, totcnt );
}
}
static void ShowGrpList( PCJobListItem *list, PCINT32 count, BOOL isFirst, int totcnt ) {
if ( count < 0 ) return;
if ( gListShowBase ) {
PrintLine( NULL, 1 );
ShowGrpListWithBase( list, count, isFirst );
if ( totcnt >= 0 ) PrintLine( colDash, 1 );
}
if ( gListShowIO ) {
PrintLine( NULL, 1 );
ShowGrpListWithIo( list, count, isFirst );
if ( totcnt >= 0 ) PrintLine( colDash, 1 );
}
if ( gListShowMem ) {
PrintLine( NULL, 1 );
ShowGrpListWithMem( list, count, isFirst );
if ( totcnt >= 0 ) PrintLine( colDash, 1 );
}
if ( gListShowProc ) {
PrintLine( NULL, 1 );
ShowGrpListWithProc( list, count, isFirst );
if ( totcnt >= 0 ) PrintLine( colDash, 1 );
}
if ( gListShowTime ) {
PrintLine( NULL, 1 );
ShowGrpListWithTime( list, count, isFirst );
if ( totcnt >= 0 ) PrintLine( colDash, 1 );
}
if ( totcnt >= 0 ) {
PrintHelp( HELP_LIST );
ToolMsg( PCCLIMSG_RETRIEVED_GROUP_LIST, totcnt );
}
}
static void ShowGrpListWithBase( PCJobListItem *list, PCINT32 count, BOOL isFirst ) {
static PCTableDef baseProcTable[] = {
{ COLHEAD_BASEPROCDATA_FLAGS, COLHEAD_BASEPROCDATA_FLAGS, 8, 8, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_BASEPROCDATA_GROUP_NAME_LONG, COLHEAD_BASEPROCDATA_GROUP_NAME_SHORT, JOB_NAME_LEN, 34, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_BASEPROCDATA_PRIORITY, COLHEAD_BASEPROCDATA_PRIORITY, 8, 8, PCCOL_JUST_CENTER,TEXT("%c") },
{ COLHEAD_BASEPROCDATA_AFFINITY, COLHEAD_BASEPROCDATA_AFFINITY, 18, 18, PCCOL_JUST_CENTER,TEXT("0x%016I64x") },
{ COLHEAD_BASEPROCDATA_SCHED_CLASS, COLHEAD_BASEPROCDATA_SCHED_CLASS, 9, 9, PCCOL_JUST_CENTER,TEXT("%lu") },
};
if ( isFirst )
BuildTableHeader( baseProcTable, ENTRY_COUNT(baseProcTable) );
TCHAR flags[8];
for ( PCINT32 i = 0; i < count; ++i, ++list ) {
wmemset( rowData, SPACE, ENTRY_COUNT(rowData) );
ShowListFlags( list->lFlags, flags );
// Insert each data item into row...
PCINT32 lastRow = (list->lFlags & PCLFLAG_IS_RUNNING) ? ENTRY_COUNT(baseProcTable) : 2;
for ( PCINT32 j = 0; j < lastRow; ++j ) {
TCHAR dataItem[256];
// Get formatted data...
switch ( j ) {
case 0: _stprintf( dataItem, baseProcTable[j].rowFmt, flags ); break;
case 1: _stprintf( dataItem, baseProcTable[j].rowFmt, list->jobName ); break;
case 2: _stprintf( dataItem, baseProcTable[j].rowFmt, ShowPriority( list->actualPriority ) ); break;
case 3: _stprintf( dataItem, baseProcTable[j].rowFmt, list->actualAffinity ); break;
case 4: _stprintf( dataItem, baseProcTable[j].rowFmt, list->actualSchedClass ); break;
}
// Insert data into row, print if last item...
InsertTableData( baseProcTable, j, dataItem, j == lastRow - 1 );
}
}
}
static void ShowGrpListWithIo( PCJobListItem *list, PCINT32 count, BOOL isFirst ) {
static PCTableDef ioProcTable[] = {
{ COLHEAD_BASEPROCDATA_FLAGS, COLHEAD_BASEPROCDATA_FLAGS, 8, 8, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_BASEPROCDATA_GROUP_NAME_LONG, COLHEAD_BASEPROCDATA_GROUP_NAME_SHORT, JOB_NAME_LEN, 34, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_IO_PROCDATA_READ_OPS, COLHEAD_IO_PROCDATA_READ_OPS, 8, 8, PCCOL_JUST_RIGHT, TEXT("%I64u") },
{ COLHEAD_IO_PROCDATA_WRITE_OPS, COLHEAD_IO_PROCDATA_WRITE_OPS, 8, 8, PCCOL_JUST_RIGHT, TEXT("%I64u") },
{ COLHEAD_IO_PROCDATA_OTHER_OPS, COLHEAD_IO_PROCDATA_OTHER_OPS, 8, 8, PCCOL_JUST_RIGHT, TEXT("%I64u") },
{ COLHEAD_IO_PROCDATA_READ_BYTES, COLHEAD_IO_PROCDATA_READ_BYTES, 10, 10, PCCOL_JUST_RIGHT, TEXT("%I64u") },
{ COLHEAD_IO_PROCDATA_WRITE_BYTES, COLHEAD_IO_PROCDATA_WRITE_BYTES, 10, 10, PCCOL_JUST_RIGHT, TEXT("%I64u") },
{ COLHEAD_IO_PROCDATA_OTHER_BYTES, COLHEAD_IO_PROCDATA_OTHER_BYTES, 10, 10, PCCOL_JUST_RIGHT, TEXT("%I64u") },
};
if ( isFirst )
BuildTableHeader( ioProcTable, ENTRY_COUNT(ioProcTable) );
TCHAR flags[8];
for ( PCINT32 i = 0; i < count; ++i, ++list ) {
wmemset( rowData, SPACE, ENTRY_COUNT(rowData) );
ShowListFlags( list->lFlags, flags );
// Insert each data item into row...
PCINT32 lastRow = (list->lFlags & PCLFLAG_IS_RUNNING) ? ENTRY_COUNT(ioProcTable) : 2;
for ( PCINT32 j = 0; j < lastRow; ++j ) {
TCHAR dataItem[256];
// Get formatted data...
switch ( j ) {
case 0: _stprintf( dataItem, ioProcTable[j].rowFmt, flags ); break;
case 1: _stprintf( dataItem, ioProcTable[j].rowFmt, list->jobName ); break;
case 2: _stprintf( dataItem, ioProcTable[j].rowFmt, list->jobStats.ReadOperationCount ); break;
case 3: _stprintf( dataItem, ioProcTable[j].rowFmt, list->jobStats.WriteOperationCount ); break;
case 4: _stprintf( dataItem, ioProcTable[j].rowFmt, list->jobStats.OtherOperationCount ); break;
case 5: _stprintf( dataItem, ioProcTable[j].rowFmt, list->jobStats.ReadTransferCount ); break;
case 6: _stprintf( dataItem, ioProcTable[j].rowFmt, list->jobStats.WriteTransferCount ); break;
case 7: _stprintf( dataItem, ioProcTable[j].rowFmt, list->jobStats.OtherTransferCount ); break;
}
// Insert data into row, print if last item...
InsertTableData( ioProcTable, j, dataItem, j == lastRow - 1 );
}
}
}
static void ShowGrpListWithMem( PCJobListItem *list, PCINT32 count, BOOL isFirst ) {
static PCTableDef memProcTable[] = {
{ COLHEAD_BASEPROCDATA_FLAGS, COLHEAD_BASEPROCDATA_FLAGS, 8, 8, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_BASEPROCDATA_GROUP_NAME_LONG, COLHEAD_BASEPROCDATA_GROUP_NAME_SHORT, JOB_NAME_LEN, 34, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_MEM_PROCDATA_PAGE_FAULTS, COLHEAD_MEM_PROCDATA_PAGE_FAULTS, 12, 12, PCCOL_JUST_RIGHT, TEXT("%lu") },
{ COLHEAD_MEM_PROCDATA_PEAK_PROC, COLHEAD_MEM_PROCDATA_PEAK_PROC, 18, 18, PCCOL_JUST_RIGHT, TEXT("%I64uK") },
{ COLHEAD_MEM_PROCDATA_PEAK_GROUP, COLHEAD_MEM_PROCDATA_PEAK_GROUP, 18, 18, PCCOL_JUST_RIGHT, TEXT("%I64uK") },
};
if ( isFirst )
BuildTableHeader( memProcTable, ENTRY_COUNT(memProcTable) );
TCHAR flags[8];
for ( PCINT32 i = 0; i < count; ++i, ++list ) {
wmemset( rowData, SPACE, ENTRY_COUNT(rowData) );
ShowListFlags( list->lFlags, flags );
// Insert each data item into row...
PCINT32 lastRow = (list->lFlags & PCLFLAG_IS_RUNNING) ? ENTRY_COUNT(memProcTable) : 2;
for ( PCINT32 j = 0; j < lastRow; ++j ) {
TCHAR dataItem[256];
// Get formatted data...
switch ( j ) {
case 0: _stprintf( dataItem, memProcTable[j].rowFmt, flags ); break;
case 1: _stprintf( dataItem, memProcTable[j].rowFmt, list->jobName ); break;
case 2: _stprintf( dataItem, memProcTable[j].rowFmt, list->jobStats.ReadOperationCount ); break;
case 3: _stprintf( dataItem, memProcTable[j].rowFmt, list->jobStats.WriteOperationCount ); break;
case 4: _stprintf( dataItem, memProcTable[j].rowFmt, list->jobStats.OtherOperationCount ); break;
}
// Insert data into row, print if last item...
InsertTableData( memProcTable, j, dataItem, j == lastRow - 1 );
}
}
}
static void ShowGrpListWithProc( PCJobListItem *list, PCINT32 count, BOOL isFirst ) {
static PCTableDef procProcTable[] = {
{ COLHEAD_BASEPROCDATA_FLAGS, COLHEAD_BASEPROCDATA_FLAGS, 8, 8, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_BASEPROCDATA_GROUP_NAME_LONG, COLHEAD_BASEPROCDATA_GROUP_NAME_SHORT, JOB_NAME_LEN, 34, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_PROC_PROCDATA_CURR_PROCS, COLHEAD_PROC_PROCDATA_CURR_PROCS, 12, 12, PCCOL_JUST_RIGHT, TEXT("%lu") },
{ COLHEAD_PROC_PROCDATA_TERM_PROCS, COLHEAD_PROC_PROCDATA_TERM_PROCS, 12, 12, PCCOL_JUST_RIGHT, TEXT("%lu") },
{ COLHEAD_PROC_PROCDATA_TOTAL_PROCS, COLHEAD_PROC_PROCDATA_TOTAL_PROCS, 12, 12, PCCOL_JUST_RIGHT, TEXT("%lu") },
};
if ( isFirst )
BuildTableHeader( procProcTable, ENTRY_COUNT(procProcTable) );
TCHAR flags[8];
for ( PCINT32 i = 0; i < count; ++i, ++list ) {
wmemset( rowData, SPACE, ENTRY_COUNT(rowData) );
ShowListFlags( list->lFlags, flags );
// Insert each data item into row...
PCINT32 lastRow = (list->lFlags & PCLFLAG_IS_RUNNING) ? ENTRY_COUNT(procProcTable) : 2;
for ( PCINT32 j = 0; j < lastRow; ++j ) {
TCHAR dataItem[256];
// Get formatted data...
switch ( j ) {
case 0: _stprintf( dataItem, procProcTable[j].rowFmt, flags ); break;
case 1: _stprintf( dataItem, procProcTable[j].rowFmt, list->jobName ); break;
case 2: _stprintf( dataItem, procProcTable[j].rowFmt, list->jobStats.ActiveProcesses ); break;
case 3: _stprintf( dataItem, procProcTable[j].rowFmt, list->jobStats.TotalTerminatedProcesses ); break;
case 4: _stprintf( dataItem, procProcTable[j].rowFmt, list->jobStats.TotalProcesses ); break;
}
// Insert data into row, print if last item...
InsertTableData( procProcTable, j, dataItem, j == lastRow - 1 );
}
}
}
static void ShowGrpListWithTime( PCJobListItem *list, PCINT32 count, BOOL isFirst ) {
static PCTableDef timeProcTable[] = {
{ COLHEAD_BASEPROCDATA_FLAGS, COLHEAD_BASEPROCDATA_FLAGS, 8, 8, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_BASEPROCDATA_GROUP_NAME_LONG, COLHEAD_BASEPROCDATA_GROUP_NAME_SHORT, JOB_NAME_LEN, 34, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_TIME_PROCDATA_USER_TIME, COLHEAD_TIME_PROCDATA_USER_TIME, 12, 12, PCCOL_JUST_RIGHT, TEXT("%I64d") },
{ COLHEAD_TIME_PROCDATA_KERNEL_TIME, COLHEAD_TIME_PROCDATA_KERNEL_TIME, 12, 12, PCCOL_JUST_RIGHT, TEXT("%I64d") },
{ COLHEAD_TIME_PROCDATA_USER_INTVL, COLHEAD_TIME_PROCDATA_USER_INTVL, 12, 12, PCCOL_JUST_RIGHT, TEXT("%I64d") },
{ COLHEAD_TIME_PROCDATA_KERNEL_INTVL, COLHEAD_TIME_PROCDATA_KERNEL_INTVL, 12, 12, PCCOL_JUST_RIGHT, TEXT("%I64d") },
};
if ( isFirst )
BuildTableHeader( timeProcTable, ENTRY_COUNT(timeProcTable) );
TCHAR flags[8];
for ( PCINT32 i = 0; i < count; ++i, ++list ) {
wmemset( rowData, SPACE, ENTRY_COUNT(rowData) );
ShowListFlags( list->lFlags, flags );
// Insert each data item into row...
PCINT32 lastRow = (list->lFlags & PCLFLAG_IS_RUNNING) ? ENTRY_COUNT(timeProcTable) : 2;
for ( PCINT32 j = 0; j < lastRow; ++j ) {
TCHAR dataItem[256];
// Get formatted data...
switch ( j ) {
case 0: _stprintf( dataItem, timeProcTable[j].rowFmt, flags ); break;
case 1: _stprintf( dataItem, timeProcTable[j].rowFmt, list->jobName ); break;
case 2: _stprintf( dataItem, timeProcTable[j].rowFmt, list->jobStats.TotalUserTime / 10000 ); break;
case 3: _stprintf( dataItem, timeProcTable[j].rowFmt, list->jobStats.TotalKernelTime / 10000 ); break;
case 4: _stprintf( dataItem, timeProcTable[j].rowFmt, list->jobStats.ThisPeriodTotalUserTime / 10000 ); break;
case 5: _stprintf( dataItem, timeProcTable[j].rowFmt, list->jobStats.ThisPeriodTotalKernelTime / 10000 ); break;
}
// Insert data into row, print if last item...
InsertTableData( timeProcTable, j, dataItem, j == lastRow - 1 );
}
}
}
static void ShowGrpSummary( PCJobSummary *list, PCINT32 count, BOOL isFirst, int totcnt ) {
static PCTableDef grpSummTable[] = {
{ COLHEAD_GRPSUMMARY_GRPNAME_LONG, COLHEAD_GRPSUMMARY_GRPNAME_SHORT, JOB_NAME_LEN, 20, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_GRPSUMMARY_FLAGS, COLHEAD_GRPSUMMARY_FLAGS, 15, 15, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_GRPSUMMARY_AFFINITY, COLHEAD_GRPSUMMARY_AFFINITY, 18, 18, PCCOL_JUST_CENTER, TEXT("0x%016I64x") },
{ COLHEAD_GRPSUMMARY_PRIORITY, COLHEAD_GRPSUMMARY_PRIORITY, 3, 3, PCCOL_JUST_CENTER, TEXT("%c") },
{ COLHEAD_GRPSUMMARY_SCHDCLASS, COLHEAD_GRPSUMMARY_SCHDCLASS, 4, 4, PCCOL_JUST_CENTER, TEXT("%lu") },
{ COLHEAD_GRPSUMMARY_PROCESS_MEMORY, COLHEAD_GRPSUMMARY_PROCESS_MEMORY, 9, 9, PCCOL_JUST_RIGHT, TEXT("%I64uK") },
{ COLHEAD_GRPSUMMARY_GROUP_MEMORY, COLHEAD_GRPSUMMARY_GROUP_MEMORY, 9, 9, PCCOL_JUST_RIGHT, TEXT("%I64uK") },
{ COLHEAD_GRPSUMMARY_PROCESS_TIME, COLHEAD_GRPSUMMARY_PROCESS_TIME, 11, 11, PCCOL_JUST_RIGHT, TEXT("%I64u") },
{ COLHEAD_GRPSUMMARY_GROUP_TIME, COLHEAD_GRPSUMMARY_GROUP_TIME, 11, 11, PCCOL_JUST_RIGHT, TEXT("%I64u") },
{ COLHEAD_GRPSUMMARY_PROCESS_COUNT, COLHEAD_GRPSUMMARY_PROCESS_COUNT, 12, 12, PCCOL_JUST_RIGHT, TEXT("%u") },
{ COLHEAD_GRPSUMMARY_WORKSET_MIN, COLHEAD_GRPSUMMARY_WORKSET_MIN, 7, 7, PCCOL_JUST_RIGHT, TEXT("%I64uK") },
{ COLHEAD_GRPSUMMARY_WORKSET_MAX, COLHEAD_GRPSUMMARY_WORKSET_MAX, 7, 7, PCCOL_JUST_RIGHT, TEXT("%I64uK") },
};
if ( count < 0 ) return;
if ( isFirst )
BuildTableHeader( grpSummTable, ENTRY_COUNT(grpSummTable) );
for ( PCINT32 i = 0; i < count; ++i, ++list ) {
// Clear and insert group name into row...
wmemset( rowData, SPACE, ENTRY_COUNT(rowData) );
InsertTableData( grpSummTable, 0, list->jobName, FALSE );
// Add remining group summary data items...
ShowMgmtParmsAsList( grpSummTable, ENTRY_COUNT(grpSummTable), 1, list->mgmtParms, TRUE );
}
if ( totcnt >= 0 ) {
PrintLine( colDash, 1 );
PrintHelp( HELP_MGMT );
ToolMsg( PCCLIMSG_RETRIEVED_GROUP_SUMMARY_LIST, totcnt );
}
}
static void ShowProcSummary( PCProcSummary *list, PCINT32 count, BOOL isFirst, int totcnt ) {
static PCTableDef procSummTable[] = {
{ COLHEAD_PROCSUMMARY_PROCNAME_LONG, COLHEAD_PROCSUMMARY_PROCNAME_SHORT, PROC_NAME_LEN, 21, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_PROCSUMMARY_GRPNAME_LONG, COLHEAD_PROCSUMMARY_GRPNAME_SHORT, JOB_NAME_LEN, 20, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_PROCSUMMARY_FLAGS, COLHEAD_PROCSUMMARY_FLAGS, 15, 15, PCCOL_JUST_LEFT, TEXT("%s") },
{ COLHEAD_PROCSUMMARY_AFFINITY, COLHEAD_PROCSUMMARY_AFFINITY, 18, 18, PCCOL_JUST_CENTER, TEXT("0x%016I64x") },
{ COLHEAD_PROCSUMMARY_PRIORITY, COLHEAD_PROCSUMMARY_PRIORITY, 3, 3, PCCOL_JUST_CENTER, TEXT("%c") },
{ COLHEAD_PROCSUMMARY_WORKSET_MIN, COLHEAD_PROCSUMMARY_WORKSET_MIN, 7, 7, PCCOL_JUST_RIGHT, TEXT("%I64uK") },
{ COLHEAD_PROCSUMMARY_WORKSET_MAX, COLHEAD_PROCSUMMARY_WORKSET_MAX, 7, 7, PCCOL_JUST_RIGHT, TEXT("%I64uK") },
};
if ( count < 0 ) return;
if ( isFirst )
BuildTableHeader( procSummTable, ENTRY_COUNT(procSummTable) );
for ( PCINT32 i = 0; i < count; ++i, ++list ) {
// Clear and insert process and group names into row...
wmemset( rowData, SPACE, ENTRY_COUNT(rowData) );
InsertTableData( procSummTable, 0, list->procName, FALSE );
InsertTableData( procSummTable, 1, list->memberOfJobName, FALSE );
// Add remining group summary data items...
ShowMgmtParmsAsList( procSummTable, ENTRY_COUNT(procSummTable), 2, list->mgmtParms, FALSE );
}
if ( totcnt >= 0 ) {
PrintLine( colDash, 1 );
PrintHelp( HELP_MGMT, FALSE, PCCLIMSG_NOTE_PROCESS_RULES_MAY_NOT_APPLY );
ToolMsg( PCCLIMSG_RETRIEVED_PROCESS_SUMMARY_LIST, totcnt );
}
}
static void ShowMgmtParmsAsList( PCTableDef *table,
PCULONG32 entries,
PCULONG32 first,
MGMT_PARMS &parm,
BOOL isGrp ) {
TCHAR flags[16], dataItem[256];
ShowMgmtFlags( flags, parm.mFlags );
for ( PCULONG32 j = first; j < entries; ++j ) {
// Get formatted data...
if ( isGrp ) switch ( j ) {
case 1: _stprintf( dataItem, table[j].rowFmt, flags ); break;
case 2: _stprintf( dataItem, table[j].rowFmt, parm.affinity ); break;
case 3: _stprintf( dataItem, table[j].rowFmt, ShowPriority( parm.priority ) ); break;
case 4: _stprintf( dataItem, table[j].rowFmt, parm.schedClass ); break;
case 5: _stprintf( dataItem, table[j].rowFmt, parm.procMemoryLimit / 1024 ); break;
case 6: _stprintf( dataItem, table[j].rowFmt, parm.jobMemoryLimit / 1024 ); break;
case 7: _stprintf( dataItem, table[j].rowFmt, parm.procTimeLimitCNS / 10000 ); break;
case 8: _stprintf( dataItem, table[j].rowFmt, parm.jobTimeLimitCNS / 10000 ); break;
case 9: _stprintf( dataItem, table[j].rowFmt, parm.procCountLimit ); break;
case 10:_stprintf( dataItem, table[j].rowFmt, parm.minWS / 1024 ); break;
case 11:_stprintf( dataItem, table[j].rowFmt, parm.maxWS / 1024 ); break;
}
else switch (j ) {
case 2: _stprintf( dataItem, table[j].rowFmt, flags ); break;
case 3: _stprintf( dataItem, table[j].rowFmt, parm.affinity ); break;
case 4: _stprintf( dataItem, table[j].rowFmt, ShowPriority( parm.priority ) ); break;
case 5: _stprintf( dataItem, table[j].rowFmt, parm.minWS / 1024 ); break;
case 6: _stprintf( dataItem, table[j].rowFmt, parm.maxWS / 1024 ); break;
}
// Insert data into row, print if last item...
InsertTableData( table, j, dataItem, j == entries - 1 );
}
}
static void ShowGrpDetail( PCJobDetail &grpDetail ) {
ToolMsg( PCCLIMSG_GROUP_DETAIL_HEADER, grpDetail.base.jobName );
ShowMgmtParms( grpDetail.base.mgmtParms, TRUE );
ShowVariableData( grpDetail.vLength, grpDetail.vData );
PrintHelp( HELP_MGMT );
}
static void ShowProcDetail( PCProcDetail &procDetail ) {
ToolMsg( PCCLIMSG_PROCESS_DETAIL_HEADER, procDetail.base.procName, ERROR_SUCCESS,
procDetail.base.memberOfJobName );
ShowMgmtParms( procDetail.base.mgmtParms, FALSE );
ShowVariableData( procDetail.vLength, procDetail.vData );
PrintHelp( HELP_MGMT, FALSE );
}
static void PrintLine( TCHAR *data, PCUINT32 nlCount ) {
DWORD numWritten;
static HANDLE stdOut = INVALID_HANDLE_VALUE;
if (stdOut == INVALID_HANDLE_VALUE) {
stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
}
if ( data ) {
DWORD len = _tcslen(data);
if (! WriteConsole(stdOut,
data,
len,
&numWritten,
0)) {
WriteFile(stdOut,
data,
len * sizeof(TCHAR),
&numWritten,
NULL);
}
}
if ( nlCount ) {
for ( PCUINT32 i = 0; i < nlCount; ++i )
if (! WriteConsole(stdOut,
TEXT("\n"),
1,
&numWritten,
0)) {
WriteFile(stdOut,
TEXT("\n"),
sizeof(TCHAR),
&numWritten,
NULL);
}
}
}
static void PrintHelp( PCUINT32 flags, BOOL isGrp, PCUINT32 msgId ) {
if ( flags & HELP_LIST ) ToolMsg( PCCLIMSG_LIST_FLAGS_EXPLAIN );
else if ( flags & HELP_ALIAS ) ToolMsg( PCCLIMSG_ALIAS_FLAGS_EXPLAIN );
else if ( flags & HELP_MGMT ) ToolMsg( isGrp? PCCLIMSG_GROUP_FLAGS_EXPLAIN :
PCCLIMSG_PROCESS_FLAGS_EXPLAIN );
if ( msgId ) ToolMsg( msgId );
}
static void BuildSystemParms( PCSystemParms &newParms, TCHAR **pArgs, PCUINT32 pArgCt ) {
memset( &newParms, 0, sizeof(newParms) );
if ( pArgCt > 0 ) newParms.manageIntervalSeconds = GetInteger( *pArgs++ );
if ( pArgCt > 1 ) newParms.timeoutValueMs = GetInteger( *pArgs++ );
}
static void BuildNameRule( PCNameRule &newRule, TCHAR **pArgs, PCUINT32 pArgCt ) {
memset( &newRule, 0, sizeof(newRule) );
if ( pArgCt > 0 ) newRule.matchType = **pArgs++;
if ( pArgCt > 1 ) _tcsncpy( newRule.matchString, *pArgs++, MATCH_STRING_LEN );
if ( pArgCt > 2 ) _tcsncpy( newRule.procName, *pArgs++, PROC_NAME_LEN );
if ( pArgCt > 3 ) _tcsncpy( newRule.description, *pArgs, NAME_DESCRIPTION_LEN );
}
static void MergeManagmentParms( MGMT_PARMS &newParms, MGMT_PARMS &oldParms ) {
newParms.mFlags |= oldParms.mFlags;
if ( !newParms.affinity ) newParms.affinity = oldParms.affinity;
if ( !newParms.jobMemoryLimit ) newParms.jobMemoryLimit = oldParms.jobMemoryLimit;
if ( !newParms.jobTimeLimitCNS ) newParms.jobTimeLimitCNS = oldParms.jobTimeLimitCNS;
if ( !newParms.maxWS ) newParms.maxWS = oldParms.maxWS;
if ( !newParms.minWS ) newParms.minWS = oldParms.minWS;
if ( !newParms.priority ) newParms.priority = oldParms.priority;
if ( !newParms.procCountLimit ) newParms.procCountLimit = oldParms.procCountLimit;
if ( !newParms.procMemoryLimit ) newParms.procMemoryLimit = oldParms.procMemoryLimit;
if ( !newParms.procTimeLimitCNS ) newParms.procTimeLimitCNS = oldParms.procTimeLimitCNS;
if ( newParms.schedClass > 9 ) newParms.schedClass = oldParms.schedClass;
if ( !*newParms.description ) memcpy( newParms.description, oldParms.description, sizeof(newParms.description) );
if ( !*newParms.profileName ) memcpy( newParms.profileName, oldParms.profileName, sizeof(newParms.profileName) );
}
static void MergeGroupDetail( PCJobDetail &newDet, PCJobDetail &oldDet ) {
if ( !newDet.vLength && oldDet.vLength ) {
newDet.vLength = oldDet.vLength;
memcpy( newDet.vData, oldDet.vData, newDet.vLength );
}
MergeManagmentParms( newDet.base.mgmtParms, oldDet.base.mgmtParms );
}
static void MergeProcDetail( PCProcDetail &newDet, PCProcDetail &oldDet ) {
if ( !newDet.vLength && oldDet.vLength ) {
newDet.vLength = oldDet.vLength;
memcpy( newDet.vData, oldDet.vData, newDet.vLength );
}
if ( !*newDet.base.memberOfJobName )
memcpy( newDet.base.memberOfJobName, oldDet.base.memberOfJobName, sizeof(newDet.base.memberOfJobName) );
MergeManagmentParms( newDet.base.mgmtParms, oldDet.base.mgmtParms );
}
static void BuildGrpDetail( PCJobDetail &newDetail, TCHAR **pArgs, PCUINT32 pArgCt ) {
memset( &newDetail, 0, offsetof(PCJobDetail, vLength) );
if ( pArgCt > 0 ) _tcsncpy( newDetail.base.jobName, *pArgs, JOB_NAME_LEN );
if ( pArgCt > 1 ) BuildMgmtParms( newDetail.base.mgmtParms, pArgs + 1, pArgCt - 1, NULL,
&newDetail.vLength, newDetail.vData );
else newDetail.vLength = 0;
}
static void BuildProcDetail( PCProcDetail &newDetail, TCHAR **pArgs, PCUINT32 pArgCt ) {
memset( &newDetail, 0, offsetof(PCProcDetail, vLength) );
if ( pArgCt > 0 ) _tcsncpy( newDetail.base.procName, *pArgs++, PROC_NAME_LEN );
if ( pArgCt > 1 ) BuildMgmtParms( newDetail.base.mgmtParms, pArgs, pArgCt - 1,
newDetail.base.memberOfJobName, &newDetail.vLength, newDetail.vData );
else newDetail.vLength = 0;
}
static void BuildGrpSummary( PCJobSummary &newSummary, TCHAR **pArgs, PCUINT32 pArgCt, PCUINT32 *listFlags ) {
memset( &newSummary, 0, sizeof(newSummary) );
if ( pArgCt > 0 ) {
_tcsncpy( newSummary.jobName, *pArgs++, JOB_NAME_LEN );
*listFlags |= PC_LIST_STARTING_WITH;
}
if ( pArgCt > 1 ) BuildMgmtParms( newSummary.mgmtParms, pArgs, pArgCt - 1 );
}
static void BuildProcSummary( PCProcSummary &newSummary, TCHAR **pArgs, PCUINT32 pArgCt, PCUINT32 *listFlags ) {
memset( &newSummary, 0, sizeof(newSummary) );
if ( pArgCt > 0 ) {
_tcsncpy( newSummary.procName, *pArgs++, PROC_NAME_LEN );
*listFlags |= PC_LIST_STARTING_WITH;
}
if ( pArgCt > 1 ) BuildMgmtParms( newSummary.mgmtParms, pArgs, pArgCt - 1, newSummary.memberOfJobName );
}
static void BuildGrpListItem( PCJobListItem &newListItem, TCHAR **pArgs, PCUINT32 pArgCt, PCUINT32 *listFlags ) {
memset( &newListItem, 0, sizeof(newListItem) );
gListShowBase = gListShowIO = gListShowMem = gListShowProc = gListShowTime = FALSE;
for ( PCUINT32 i = 0; i < pArgCt; ++i, ++pArgs ) {
if ( !IsSwitch( **pArgs ) ) {
_tcsncpy( newListItem.jobName, *pArgs, JOB_NAME_LEN );
*listFlags |= PC_LIST_STARTING_WITH;
}
else switch ( (*pArgs)[1] ) {
case GL_ALL:
gListShowTime = gListShowBase = gListShowIO = gListShowMem = gListShowProc = TRUE; break;
case GL_BASE: gListShowBase = TRUE; break;
case GL_IO: gListShowIO = TRUE; break;
case GL_MEMORY: gListShowMem = TRUE; break;
case GL_PROCESS: gListShowProc = TRUE; break;
case GL_TIME: gListShowTime = TRUE; break;
default:
ToolMsg( PCCLIMSG_GROUP_LIST_FLAG_UNKNOWN, *pArgs );
}
}
if ( !gListShowIO && !gListShowMem && !gListShowProc && !gListShowTime )
gListShowBase = TRUE;
}
static void BuildProcListItem( PCProcListItem &newListItem, TCHAR **pArgs, PCUINT32 pArgCt, PCUINT32 *listFlags ) {
memset( &newListItem, 0, sizeof(newListItem) );
gShowFmtProcTime = FALSE;
while ( pArgCt > 0 ) {
if ( IsSwitch( **pArgs) ) {
if ( *(*pArgs + 1) == DATA_GROUP && pArgCt > 1 ) {
_tcsncpy( newListItem.jobName, *++pArgs, JOB_NAME_LEN );
++pArgs;
pArgCt -= 2;
*listFlags |= PC_LIST_MEMBERS_OF;
}
else if ( *(*pArgs + 1) == TEXT('t') ) {
gShowFmtProcTime = TRUE;
++pArgs;
--pArgCt;
}
else {
ToolMsg( PCCLIMSG_PROCESS_LIST_FLAG_UNKNOWN, *pArgs );
break;
}
}
else {
_tcsncpy( newListItem.procName, *pArgs++, PROC_NAME_LEN );
--pArgCt;
if ( pArgCt > 0 && !IsSwitch( **pArgs) ) {
newListItem.procStats.pid = GetUInteger64( *pArgs++ );
--pArgCt;
}
*listFlags |= PC_LIST_STARTING_WITH;
}
}
if ( pArgCt ) ToolMsg( PCCLIMSG_PROCESS_LIST_FLAG_IGNORED, *pArgs );
}
static void BuildMgmtParms( MGMT_PARMS &parm,
TCHAR **pArgs,
PCUINT32 pArgCt,
JOB_NAME grpHere,
PCINT16 *len,
TCHAR *var ) {
PCUINT32 inLen = len? *len : 0;
if ( len ) *len = 0;
parm.schedClass = 99; // set 'net set' value. Needed because 0 is a valid setting.
for ( ; pArgCt > 1; pArgCt -= 2 ) {
if ( !IsSwitch( **pArgs ) ) {
ToolMsg( PCCLIMSG_UNKNOWN_DEF_SWITCH_IGNORED, *pArgs );
return;
}
if ( IsSwitch( **(pArgs + 1) ) ) {
ToolMsg( PCCLIMSG_ARG_MISSING_WITH_IGNORE, *pArgs );
return;
}
switch ( *(*pArgs++ + 1) ) {
case DEF_PRIO:
parm.priority = GetPriority( *pArgs++ );
if ( !parm.priority )
ToolMsg( PCCLIMSG_UNKNOWN_PRIORITY_IGNORED, *(pArgs - 1) );
break;
case DEF_AFF:
parm.affinity = GetUInteger64( *pArgs++ );
break;
case DEF_WS:
if ( pArgCt > 2 ) {
parm.minWS = GetValue( *pArgs++, MAXLONG - 1 ) * 1024; // Limit to match snap-in's limit
if ( !IsSwitch( **pArgs ) )
parm.maxWS = GetValue( *pArgs++, MAXLONG - 1 ) * 1024; // Limit to match snap-in's limit
else {
parm.minWS = 0;
ToolMsg( PCCLIMSG_WS_MAX_MISSING, *(pArgs - 1) );
return;
}
--pArgCt;
}
break;
case DEF_SCHED:
parm.schedClass = GetInteger( *pArgs++ );
break;
case DEF_FLAGS:
parm.mFlags = GetMgtFlags( *pArgs++ );
break;
case DEF_PROCTIME:
parm.procTimeLimitCNS = GetInteger64( *pArgs++ ) * 10000;
break;
case DEF_GROUP:
if ( grpHere ) _tcsncpy( grpHere, *pArgs++, JOB_NAME_LEN );
else
ToolMsg( PCCLIMSG_GROUP_NAME_NOT_APPLICABLE );
break;
case DEF_GROUPTIME:
parm.jobTimeLimitCNS = GetInteger64( *pArgs++ ) * 10000;
break;
case DEF_GROUPMEM:
parm.jobMemoryLimit = GetValue( *pArgs++, MAXLONG - 1 ) * 1024; // Limit to match snap-in's limit
break;
case DEF_PROCMEM:
parm.procMemoryLimit = GetValue( *pArgs++, MAXLONG - 1 ) * 1024; // Limit to match snap-in's limit
break;
case DEF_PROCCOUNT:
parm.procCountLimit = (ULONG) GetValue( *pArgs++, MAXLONG - 1 ); // Limit to match snap-in's limit
break;
case DEF_BRKAWAY:
parm.mFlags |= PCMFLAG_SET_PROC_BREAKAWAY_OK;
break;
case DEF_SILENTBRKAWAY:
parm.mFlags |= PCMFLAG_SET_SILENT_BREAKAWAY;
break;
case DEF_DIEONUHEX:
parm.mFlags |= PCMFLAG_SET_DIE_ON_UH_EXCEPTION;
break;
case DEF_CLOSEONEMPTY:
parm.mFlags |= PCMFLAG_END_JOB_WHEN_EMPTY;
break;
case DEF_MSGONGRPTIME:
parm.mFlags |= PCMFLAG_MSG_ON_JOB_TIME_LIMIT_HIT;
break;
case DEF_PROF:
_tcsncpy( parm.profileName, *pArgs++, PROFILE_NAME_LEN );
break;
case DEF_DESC:
_tcsncpy( parm.description, *pArgs++, RULE_DESCRIPTION_LEN );
break;
case DEF_VARDATA:
if ( inLen ) {
*len = (PCINT16) min( (_tcslen( *pArgs ) + 1), inLen / sizeof(TCHAR) );
if ( *len ) _tcsncpy( var, *pArgs, *len );
*len *= sizeof(TCHAR); // convert to bytes as per definition of field
}
*pArgs++;
break;
default:
ToolMsg( PCCLIMSG_UNKNOWN_DEF_SWITCH_IGNORED, *--pArgs );
return;
break;
}
}
if ( pArgCt )
ToolMsg( PCCLIMSG_INCOMPLETE_DEFINITION_IGNORED, *pArgs );
}
static PC_MGMT_FLAGS GetMgtFlags( TCHAR *txt ) {
PC_MGMT_FLAGS flgs = 0;
for ( TCHAR *d = txt; *d; ++d ) {
TCHAR c = _totlower( *d );
if ( c == DEF_GROUP ) flgs |= PCMFLAG_APPLY_JOB_MEMBERSHIP;
else if ( c == DEF_AFF ) flgs |= PCMFLAG_APPLY_AFFINITY;
else if ( c == DEF_PRIO ) flgs |= PCMFLAG_APPLY_PRIORITY;
else if ( c == DEF_WS ) flgs |= PCMFLAG_APPLY_WS_MINMAX;
else if ( c == DEF_SCHED ) flgs |= PCMFLAG_APPLY_SCHEDULING_CLASS;
else if ( c == DEF_PROCTIME ) flgs |= PCMFLAG_APPLY_PROC_TIME_LIMIT;
else if ( c == DEF_GROUPTIME ) flgs |= PCMFLAG_APPLY_JOB_TIME_LIMIT;
else if ( c == DEF_GROUPMEM ) flgs |= PCMFLAG_APPLY_JOB_MEMORY_LIMIT;
else if ( c == DEF_PROCMEM ) flgs |= PCMFLAG_APPLY_PROC_MEMORY_LIMIT;
else if ( c == DEF_PROCCOUNT ) flgs |= PCMFLAG_APPLY_PROC_COUNT_LIMIT;
else if ( c == DEF_BRKAWAY ) flgs |= PCMFLAG_SET_PROC_BREAKAWAY_OK;
else if ( c == DEF_SILENTBRKAWAY ) flgs |= PCMFLAG_SET_SILENT_BREAKAWAY;
else if ( c == DEF_DIEONUHEX ) flgs |= PCMFLAG_SET_DIE_ON_UH_EXCEPTION;
else if ( c == DEF_CLOSEONEMPTY ) flgs |= PCMFLAG_END_JOB_WHEN_EMPTY;
else if ( c == DEF_MSGONGRPTIME ) flgs |= PCMFLAG_MSG_ON_JOB_TIME_LIMIT_HIT;
}
return flgs;
}
static void ShowMgmtParms( MGMT_PARMS &parm, BOOL isGrp ) {
TCHAR flags[16];
ShowMgmtFlags( flags, parm.mFlags );
if ( isGrp )
ToolMsg( PCCLIMSG_GROUP_DETAIL_PARAMETERS, flags, ERROR_SUCCESS,
(VOID *) parm.affinity, (VOID *) ShowPriority( parm.priority ),
IntToPtr(parm.schedClass),
(VOID *) (parm.procMemoryLimit / 1024), (VOID *) (parm.jobMemoryLimit / 1024),
(VOID *) (parm.procTimeLimitCNS / 10000), (VOID *) (parm.jobTimeLimitCNS / 10000),
IntToPtr(parm.procCountLimit),
(VOID *) (parm.minWS / 1024), (VOID *) (parm.maxWS / 1024) );
else
ToolMsg( PCCLIMSG_PROCESS_DETAIL_PARAMETERS, flags, ERROR_SUCCESS,
(VOID *) parm.affinity, (VOID *) ShowPriority( parm.priority ),
(VOID *) (parm.minWS / 1024), (VOID *) (parm.maxWS / 1024) );
if ( *parm.description )
ToolMsg( PCCLIMSG_DETAIL_DESCRIPTION_TEXT, parm.description );
}
static void ShowVariableData( short len, TCHAR *data ) {
if ( len )
ToolMsg( PCCLIMSG_DETAIL_VARIABLE_TEXT, IntToPtr(len), ERROR_SUCCESS, IntToPtr(len / 2), data );
}
static void ShowMgmtFlags( TCHAR flags[16], PC_MGMT_FLAGS mFlags, BOOL compact ) {
for ( PCUINT32 i = 0; i < 16; ++i ) flags[i] = TEXT('.');
flags[15] = 0;
if ( mFlags & PCMFLAG_APPLY_JOB_MEMBERSHIP ) flags[0] = _totupper(DEF_GROUP);
if ( mFlags & PCMFLAG_APPLY_PRIORITY ) flags[1] = _totupper(DEF_PRIO);
if ( mFlags & PCMFLAG_APPLY_AFFINITY ) flags[2] = _totupper(DEF_AFF);
if ( mFlags & PCMFLAG_APPLY_SCHEDULING_CLASS ) flags[3] = _totupper(DEF_SCHED);
if ( mFlags & PCMFLAG_APPLY_WS_MINMAX ) flags[4] = _totupper(DEF_WS);
if ( mFlags & PCMFLAG_SET_PROC_BREAKAWAY_OK ) flags[5] = _totupper(DEF_BRKAWAY);
if ( mFlags & PCMFLAG_SET_SILENT_BREAKAWAY ) flags[6] = _totupper(DEF_SILENTBRKAWAY);
if ( mFlags & PCMFLAG_SET_DIE_ON_UH_EXCEPTION ) flags[7] = _totupper(DEF_DIEONUHEX);
if ( mFlags & PCMFLAG_END_JOB_WHEN_EMPTY ) flags[8] = _totupper(DEF_CLOSEONEMPTY);
if ( mFlags & PCMFLAG_MSG_ON_JOB_TIME_LIMIT_HIT ) flags[9] = _totupper(DEF_MSGONGRPTIME);
if ( mFlags & PCMFLAG_APPLY_PROC_MEMORY_LIMIT ) flags[10] = _totupper(DEF_PROCMEM);
if ( mFlags & PCMFLAG_APPLY_JOB_MEMORY_LIMIT ) flags[11] = _totupper(DEF_GROUPMEM);
if ( mFlags & PCMFLAG_APPLY_JOB_TIME_LIMIT ) flags[12] = _totupper(DEF_GROUPTIME);
if ( mFlags & PCMFLAG_APPLY_PROC_TIME_LIMIT ) flags[13] = _totupper(DEF_PROCTIME);
if ( mFlags & PCMFLAG_APPLY_PROC_COUNT_LIMIT ) flags[14] = _totupper(DEF_PROCCOUNT);
if ( compact ) {
for ( PCUINT32 j = 0, i = 0; i < 15; ++i )
if ( flags[i] != TEXT('.') ) flags[j++] = flags[i];
flags[j] = 0;
}
}
static void ShowSysInfo( PCSystemInfo &sysInfo, BOOL versionOnly ) {
if ( versionOnly )
ToolMsg( PCCLIMSG_SERVICE_VERSION_SHORT, sysInfo.productVersion, ERROR_SUCCESS,
sysInfo.fileVersion, sysInfo.fileFlags );
else {
ToolMsg( PCCLIMSG_SERVICE_VERSION_LONG, sysInfo.productVersion, ERROR_SUCCESS,
sysInfo.fileVersion, sysInfo.fileFlags, IntToPtr(sysInfo.fixedSignature) );
ToolMsg( PCCLIMSG_SERVICE_VERSION_BINARY, IntToPtr(sysInfo.fixedFileVersionMS),
ERROR_SUCCESS, IntToPtr(sysInfo.fixedFileVersionLS),
IntToPtr(sysInfo.fixedProductVersionMS), IntToPtr(sysInfo.fixedProductVersionLS),
IntToPtr(sysInfo.fixedFileOS),
IntToPtr(sysInfo.fixedFileType), IntToPtr(sysInfo.fixedFileSubtype) );
ToolMsg( PCCLIMSG_MEDIATOR_VERSION_LONG, sysInfo.medProductVersion, ERROR_SUCCESS,
sysInfo.medFileVersion, sysInfo.medFileFlags );
ShowSysParms( sysInfo.sysParms );
}
}
static void ShowSysParms( PCSystemParms &sysParms ) {
ToolMsg( PCCLIMSG_SYSTEM_PARAMETERS, IntToPtr(sysParms.numberOfProcessors), ERROR_SUCCESS,
(VOID *) sysParms.processorMask, IntToPtr(sysParms.memoryPageSize),
IntToPtr(sysParms.manageIntervalSeconds), IntToPtr(sysParms.timeoutValueMs) );
}
static int ShowHelp( TCHAR **pArgs, PCUINT32 pArgCt ) {
if ( !pArgCt ) ShowCLIHelp();
else ShowDetailHelp( pArgs, pArgCt );
return 0;
}
static void ShowCLIHelp( void ) {
ToolMsg( PCCLIMSG_COMMAND_HELP, (VOID *) (PC_MIN_BUF_SIZE / 1024), ERROR_SUCCESS,
(VOID *) (PC_MAX_BUF_SIZE / 1024) );
}
static void ShowDetailHelp( TCHAR **pArgs, PCUINT32 pArgCt ) {
for ( ; pArgCt > 0; --pArgCt, ++pArgs ) {
int i = 0;
TCHAR code = (*pArgs)[i++];
if ( IsSwitch( code ) && (*pArgs)[i] ) code = (*pArgs)[i++];
TCHAR subCode = (*pArgs)[i++];
switch ( code ) {
case BUFFER_SIZE:
ToolMsg( PCCLIMSG_SWITCH_b_HELP, (VOID *) (PC_MIN_BUF_SIZE / 1024), ERROR_SUCCESS,
(VOID *) (PC_MAX_BUF_SIZE / 1024) );
break;
case COMPUTER_NAME: ToolMsg( PCCLIMSG_SWITCH_c_HELP ); break;
case INTERACTIVE: ToolMsg( PCCLIMSG_SWITCH_i_HELP ); break;
case FILE_INPUT: ToolMsg( PCCLIMSG_SWITCH_f_HELP ); break;
case ADMIN_DUMPREST:ToolMsg( PCCLIMSG_SWITCH_x_HELP ); break;
case OP_ADD: ToolMsg( PCCLIMSG_SWITCH_a_HELP ); break;
case OP_REP: ToolMsg( PCCLIMSG_SWITCH_r_HELP ); break;
case OP_UPDATE: ToolMsg( PCCLIMSG_SWITCH_u_HELP ); break;
case OP_DEL: ToolMsg( PCCLIMSG_SWITCH_d_HELP ); break;
case OP_SWAP: ToolMsg( PCCLIMSG_SWITCH_s_HELP ); break;
case OP_LIST: ToolMsg( PCCLIMSG_SWITCH_l_HELP ); break;
case OP_KILL: ToolMsg( PCCLIMSG_SWITCH_k_HELP ); break;
case OP_COMMENT: ToolMsg( PCCLIMSG_SWITCH_COMMENT_HELP ); break;
case OP_HELP: ToolMsg( PCCLIMSG_SWITCH_HELP_HELP ); break;
case DATA_GROUP:
switch ( subCode ) {
case SUB_LIST:
case 0: ToolMsg( PCCLIMSG_SWITCH_gl_HELP ); break;
case SUB_SUMMARY: ToolMsg( PCCLIMSG_SWITCH_gs_HELP ); break;
case SUB_DEFS: ToolMsg( PCCLIMSG_SWITCH_gd_HELP ); break;
default:
ToolMsg( PCCLIMSG_GROUP_SUBLIST_HELP_UNKNOWN, (VOID *) subCode, ERROR_SUCCESS,
(VOID *) SUB_DEFS, (VOID *) SUB_SUMMARY, (VOID *) SUB_LIST );
break;
}
break;
case DATA_PROC:
switch ( subCode ) {
case SUB_LIST:
case 0: ToolMsg( PCCLIMSG_SWITCH_pl_HELP ); break;
case SUB_SUMMARY: ToolMsg( PCCLIMSG_SWITCH_ps_HELP ); break;
case SUB_DEFS: ToolMsg( PCCLIMSG_SWITCH_pd_HELP ); break;
default:
ToolMsg( PCCLIMSG_PROCESS_SUBLIST_HELP_UNKNOWN, (VOID *) subCode, ERROR_SUCCESS,
(VOID *) SUB_DEFS, (VOID *) SUB_SUMMARY, (VOID *) SUB_LIST );
break;
}
break;
case DATA_NAME: ToolMsg( PCCLIMSG_SWITCH_n_HELP ); break;
case DATA_SERVICE: ToolMsg( PCCLIMSG_SWITCH_v_HELP ); break;
case DATA_MEDIATOR: ToolMsg( PCCLIMSG_SWITCH_m_HELP ); break;
default:
ToolMsg( PCCLIMSG_HELP_UNKNOWN, (VOID *) code );
return;
}
}
}