2531 lines
78 KiB
C
2531 lines
78 KiB
C
/*****************************************************************************\
|
|
|
|
Author: Corey Morgan (coreym)
|
|
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
\*****************************************************************************/
|
|
|
|
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <conio.h>
|
|
#include <tchar.h>
|
|
#include <mbctype.h>
|
|
#include <strsafe.h>
|
|
|
|
#include "varg.h"
|
|
|
|
#define VARG_ARG_PREFIX_LEN 16
|
|
#define VARG_TOKEN_LEN 2
|
|
#define VARG_VERB_PREFIX_LEN 4
|
|
|
|
LPTSTR g_strProg;
|
|
HANDLE g_hConsole;
|
|
WORD g_original;
|
|
WORD g_debug;
|
|
WORD g_light;
|
|
WORD g_dark;
|
|
WORD g_normal;
|
|
TCHAR g_strVerbPrefix[VARG_VERB_PREFIX_LEN] = _T("");
|
|
TCHAR g_strPrefix[VARG_ARG_PREFIX_LEN] = _T("-/");
|
|
TCHAR g_strArgToken[VARG_TOKEN_LEN] = _T("`");
|
|
SHORT g_X;
|
|
SHORT g_Y;
|
|
LONG g_nDebug = -1;
|
|
|
|
#define COLORIZE( c ) (WORD)((Commands[c].fFlag & (VARG_FLAG_DARKEN|VARG_FLAG_HIDDEN)) ? g_dark : g_normal)
|
|
#define HELP_INDENT 32
|
|
|
|
#define COPY_RESOURCE( dest, src, c ) \
|
|
if( IsEmpty( src ) || _tcscmp( src, c )==0 ){ \
|
|
ASSIGN_STRING( dest, NULL ); \
|
|
}else{ \
|
|
ASSIGN_STRING( dest, src ); \
|
|
} \
|
|
|
|
#define OOM( p ) if(NULL == p){ PrintError( E_OUTOFMEMORY ); FreeCmd(); exit(ERROR_OUTOFMEMORY); }
|
|
|
|
BOOL varg_strlen( LPTSTR str, ULONG* pVisualSize, ULONG* pAcutalSize );
|
|
void PrintParam( int idPrompt, int cmd, BOOL bEOL );
|
|
BOOL FindString( LPTSTR strBuffer, LPTSTR strMatch );
|
|
|
|
int varg_vprintf( WORD color, LPCTSTR mask, va_list args )
|
|
{
|
|
DWORD dwPrint;
|
|
HANDLE hOut;
|
|
BOOL bResult;
|
|
|
|
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
if( INVALID_HANDLE_VALUE == hOut ){
|
|
return 0;
|
|
}
|
|
|
|
bResult = SetConsoleTextAttribute( g_hConsole, color );
|
|
ASSERT( bResult );
|
|
|
|
__try {
|
|
LPTSTR buffer = NULL;
|
|
dwPrint = FormatMessage(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_STRING,
|
|
mask,
|
|
0,
|
|
0,
|
|
(LPTSTR)&buffer,
|
|
4096,
|
|
&args
|
|
);
|
|
|
|
if( NULL != buffer ){
|
|
ULONG len, temp;
|
|
if ((GetFileType(hOut) & ~FILE_TYPE_REMOTE) == FILE_TYPE_CHAR) {
|
|
bResult = WriteConsole( hOut, buffer, dwPrint, &dwPrint, NULL );
|
|
ASSERT( bResult );
|
|
}else{
|
|
LPSTR szAnsiBuffer = NULL;
|
|
|
|
szAnsiBuffer = (LPSTR)VARG_ALLOC( (dwPrint+1) * sizeof(WCHAR) );
|
|
if( NULL != szAnsiBuffer ){
|
|
if( CharToOem( buffer, szAnsiBuffer ) ){
|
|
bResult = WriteFile( hOut, szAnsiBuffer, strlen( szAnsiBuffer ), &temp, NULL );
|
|
ASSERT( bResult );
|
|
}
|
|
}
|
|
VARG_FREE( szAnsiBuffer );
|
|
}
|
|
|
|
if( varg_strlen( buffer, &len, NULL ) ){
|
|
dwPrint = len;
|
|
}
|
|
|
|
|
|
LocalFree( buffer );
|
|
}
|
|
|
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
FreeCmd();
|
|
exit(E_UNEXPECTED);
|
|
}
|
|
|
|
bResult = SetConsoleTextAttribute( g_hConsole, g_original );
|
|
ASSERT( bResult );
|
|
|
|
return (int)dwPrint;
|
|
}
|
|
|
|
int varg_printf( WORD color, LPCTSTR mask, ... )
|
|
{
|
|
int nPrint;
|
|
|
|
va_list args;
|
|
va_start( args, mask );
|
|
|
|
nPrint = varg_vprintf( color, mask, args );
|
|
|
|
va_end( args );
|
|
|
|
return nPrint;
|
|
}
|
|
|
|
_inline
|
|
BOOL IsArg( LPTSTR str )
|
|
{
|
|
int i;
|
|
if( str == NULL ){
|
|
return FALSE;
|
|
}
|
|
for( i=0;i<g_strPrefix[i] != _T('\0');i++){
|
|
if( str[0] == g_strPrefix[i] ){
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
_inline
|
|
BOOL IsCmd( PVARG_RECORD arg, LPTSTR str, BOOL bIni )
|
|
{
|
|
BOOL bNegated = FALSE;
|
|
|
|
if( !bIni ){
|
|
if( IsArg(str) ){
|
|
str++;
|
|
}else{
|
|
if( arg->fFlag & VARG_FLAG_NOFLAG ){
|
|
if( arg->bDefined ){
|
|
return FALSE;
|
|
}else{
|
|
return TRUE;
|
|
}
|
|
}
|
|
if( !( (arg->fFlag & VARG_FLAG_VERB) || (arg->fFlag & VARG_FLAG_ADVERB)) ){
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( str[0] == _T('-') ){
|
|
bNegated = TRUE;
|
|
str++;
|
|
}
|
|
|
|
if( ( arg->strArg1 != NULL && !_tcsicmp( str, arg->strArg1 ) ) ||
|
|
( arg->strArg2 != NULL && !_tcsicmp( str, arg->strArg2 ) ) ){
|
|
|
|
if( arg->fFlag & VARG_FLAG_NEGATE ){
|
|
arg->bNegated = bNegated;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
_inline
|
|
BOOL ArgExpected( PVARG_RECORD arg )
|
|
{
|
|
switch(arg->fType){
|
|
case VARG_TYPE_BOOL:
|
|
case VARG_TYPE_HELP:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
_inline
|
|
BOOL
|
|
IsEmpty( LPTSTR str )
|
|
{
|
|
if( str == NULL ){
|
|
return TRUE;
|
|
}
|
|
if( *str == _T('\0') ){
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
_inline BOOL
|
|
IsCharWhitespace( TCHAR ch )
|
|
{
|
|
switch( ch ){
|
|
case _T(' '):
|
|
case _T('\r'):
|
|
case _T('\n'):
|
|
case _T('\t'):
|
|
return TRUE;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
_inline
|
|
BOOL
|
|
IsDBCSCodePage()
|
|
{
|
|
switch (GetConsoleOutputCP()) {
|
|
case 932:
|
|
case 936:
|
|
case 949:
|
|
case 950:
|
|
return TRUE;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
LPTSTR varg_strdup( LPTSTR src )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
LPTSTR dest = NULL;
|
|
|
|
if( !IsEmpty(src) ){
|
|
DWORD dwSize = (_tcslen(src)+2)*sizeof(TCHAR);
|
|
dest = (LPTSTR)VARG_ALLOC( dwSize );
|
|
if( NULL != dest ){
|
|
ZeroMemory( dest, dwSize );
|
|
hr = StringCbCopy( dest, dwSize, src );
|
|
}
|
|
}else{
|
|
DWORD dwSize = 2*sizeof(TCHAR);
|
|
dest = (LPTSTR)VARG_ALLOC( dwSize );
|
|
if( NULL != dest ){
|
|
hr = StringCbCopy( dest, dwSize, _T("") );
|
|
}
|
|
}
|
|
|
|
if( FAILED(hr) ){
|
|
VARG_FREE(dest);
|
|
dest = NULL;
|
|
}
|
|
|
|
return dest;
|
|
}
|
|
|
|
BOOL
|
|
varg_cmdIsString( int id )
|
|
{
|
|
BOOL bResult = FALSE;
|
|
|
|
__try{
|
|
if( Commands[id].fType == VARG_TYPE_STR ||
|
|
Commands[id].fType == VARG_TYPE_MSZ ||
|
|
Commands[id].fType == VARG_TYPE_INI ){
|
|
|
|
bResult = TRUE;
|
|
}
|
|
|
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
bResult = FALSE;
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
DWORD
|
|
varg_cmdStringAssign( int id, LPTSTR src )
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
|
|
__try{
|
|
|
|
if( varg_cmdIsString( id ) ){
|
|
if( Commands[id].fFlag & VARG_FLAG_ALLOCSTR ){
|
|
varg_cmdStringFree( id );
|
|
}
|
|
|
|
Commands[id].strValue = varg_strdup( src );
|
|
|
|
if( NULL == Commands[id].strValue ){
|
|
dwStatus = ERROR_OUTOFMEMORY;
|
|
}else{
|
|
Commands[id].fFlag |= VARG_FLAG_ALLOCSTR;
|
|
Commands[id].fFlag &= ~VARG_FLAG_DODEFAULT;
|
|
Commands[id].fFlag &= ~VARG_FLAG_RCDEFAULT;
|
|
}
|
|
}else{
|
|
dwStatus = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
dwStatus = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
DWORD
|
|
varg_cmdStringFree( int id )
|
|
{
|
|
if( varg_cmdIsString( id ) ){
|
|
if( Commands[id].fFlag & VARG_FLAG_ALLOCSTR ){
|
|
VARG_FREE( Commands[id].strValue );
|
|
}
|
|
Commands[id].fFlag &= ~VARG_FLAG_ALLOCSTR;
|
|
Commands[id].strValue = NULL;
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
DWORD
|
|
varg_cmdStringAddMsz( int id, LPTSTR src )
|
|
{
|
|
if( varg_cmdIsString( id ) ){
|
|
if( !(Commands[id].fFlag & VARG_FLAG_ALLOCSTR) ){
|
|
Commands[id].strValue = varg_strdup( Commands[id].strValue );
|
|
}
|
|
AddStringToMsz( &Commands[id].strValue, src );
|
|
Commands[id].fFlag |= VARG_FLAG_ALLOCSTR;
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
LPWSTR
|
|
PaddedString(
|
|
LPWSTR sz,
|
|
LPWSTR buffer,
|
|
ULONG cchBufferSize,
|
|
ULONG cchPadSize
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG visual, actual;
|
|
|
|
if( _tcslen( sz ) < cchPadSize ){
|
|
|
|
hr = StringCchCopy( buffer, cchBufferSize, sz );
|
|
|
|
varg_strlen( sz, &visual, &actual );
|
|
|
|
while( visual < cchPadSize ){
|
|
hr = StringCchCat( buffer, cchBufferSize, _T(" ") );
|
|
visual++;
|
|
}
|
|
|
|
return buffer;
|
|
}else{
|
|
return sz;
|
|
}
|
|
}
|
|
|
|
void Chomp(LPTSTR pszLine)
|
|
{
|
|
size_t lLen;
|
|
LPTSTR pszLineEnd;
|
|
|
|
if( pszLine == NULL ){
|
|
return;
|
|
}
|
|
|
|
lLen = _tcslen(pszLine);
|
|
|
|
pszLineEnd = pszLine + lLen - 1;
|
|
|
|
while( pszLineEnd >= pszLine &&
|
|
(*pszLineEnd == _T(' ') ||
|
|
*pszLineEnd == _T('\r') ||
|
|
*pszLineEnd == _T('\n') ||
|
|
*pszLineEnd == _T('\t')) ){
|
|
|
|
pszLineEnd--;
|
|
}
|
|
|
|
pszLineEnd++;
|
|
|
|
if (*pszLineEnd == _T(' ') || *pszLineEnd == _T('\n') || *pszLineEnd == _T('\t') ){
|
|
*pszLineEnd = _T('\0');
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
ReadLong( LPTSTR strNumber, ULONG* pulNumber, ULONG nMax )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
LPTSTR strBuffer = NULL;
|
|
ULONG nValue;
|
|
DWORD dwStatus = ERROR_INVALID_PARAMETER;
|
|
|
|
if( NULL == strNumber ){
|
|
*pulNumber = 0;
|
|
dwStatus = ERROR_SUCCESS;
|
|
}else{
|
|
|
|
strBuffer = varg_strdup( strNumber );
|
|
|
|
if( NULL == strBuffer ){
|
|
dwStatus = ERROR_OUTOFMEMORY;
|
|
}else{
|
|
LPTSTR strEnd;
|
|
LPTSTR strBegin;
|
|
size_t count = _tcslen( strBuffer )+1;
|
|
|
|
nValue = (ULONG)_tcstod( strNumber, &strEnd );
|
|
hr = StringCchPrintf( strBuffer, count, _T("%lu"), nValue );
|
|
|
|
if( SUCCEEDED(hr) ){
|
|
strBegin = strNumber;
|
|
while( *strBegin == _T('0') && (strEnd - strBegin) > 1 ){ strBegin++; }
|
|
count = (size_t)(strEnd - strBegin);
|
|
|
|
if( (_tcsnicmp( strBuffer, strBegin, count ) == 0) ){
|
|
if( nValue <= nMax ){
|
|
*pulNumber = nValue;
|
|
dwStatus = ERROR_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
VARG_FREE( strBuffer );
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
void SetUpColors()
|
|
{
|
|
CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
|
|
HKEY hkey = NULL;
|
|
HRESULT hr;
|
|
DWORD dwColorize = 0;
|
|
g_hConsole = GetStdHandle( STD_OUTPUT_HANDLE );
|
|
GetConsoleScreenBufferInfo( g_hConsole, &ConsoleInfo );
|
|
|
|
g_original = ConsoleInfo.wAttributes;
|
|
g_X = (SHORT)(ConsoleInfo.srWindow.Right - ConsoleInfo.srWindow.Left);
|
|
g_Y = (SHORT)(ConsoleInfo.srWindow.Bottom - ConsoleInfo.srWindow.Top);
|
|
|
|
hr = RegOpenKeyExW (
|
|
HKEY_CURRENT_USER,
|
|
L"Console",
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&hkey
|
|
);
|
|
if( ERROR_SUCCESS == hr ){
|
|
DWORD dwType;
|
|
DWORD dwSize = sizeof(DWORD);
|
|
hr = RegQueryValueExW (
|
|
hkey,
|
|
L"Colorize",
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&dwColorize,
|
|
&dwSize
|
|
);
|
|
}
|
|
|
|
if( ERROR_SUCCESS == hr ){
|
|
if( dwColorize == 0xff ){
|
|
g_normal = ConsoleInfo.wAttributes;
|
|
g_light = (USHORT)(ConsoleInfo.wAttributes | FOREGROUND_INTENSITY);
|
|
g_debug = (USHORT)((ConsoleInfo.wAttributes & 0xF0) | FOREGROUND_INTENSITY | FOREGROUND_RED);
|
|
g_dark = (USHORT)((ConsoleInfo.wAttributes & 0xF0) | FOREGROUND_INTENSITY);
|
|
}else{
|
|
g_normal = (USHORT)(dwColorize & 0x000000FF);
|
|
g_debug = (USHORT)((dwColorize & 0x0000FF00) >> 8);
|
|
g_light = (USHORT)((dwColorize & 0x00FF0000) >> 16);
|
|
g_dark = (USHORT)((dwColorize & 0xFF000000) >> 24);
|
|
}
|
|
}else{
|
|
g_normal = ConsoleInfo.wAttributes;
|
|
g_debug = g_normal;
|
|
g_light = g_normal;
|
|
g_dark = g_normal;
|
|
}
|
|
|
|
if((g_dark & 0xF) == ((g_dark >> 4) & 0xF)) {
|
|
g_dark = g_normal;
|
|
}
|
|
|
|
if((g_light & 0xF) == ((g_light >> 4) & 0xF)) {
|
|
g_light = g_normal;
|
|
}
|
|
|
|
if((g_debug & 0xF) == ((g_debug >> 4) & 0xF)) {
|
|
g_debug = g_normal;
|
|
}
|
|
|
|
if( NULL != hkey ){
|
|
RegCloseKey ( hkey );
|
|
}
|
|
}
|
|
|
|
void FreeCmd()
|
|
{
|
|
int i;
|
|
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
|
|
|
|
for(i=0;Commands[i].fType != VARG_TYPE_LAST;i++){
|
|
Commands[i].bDefined = FALSE;
|
|
__try{
|
|
|
|
if( varg_cmdIsString( i ) ){
|
|
varg_cmdStringFree( i );
|
|
}
|
|
|
|
if( Commands[i].strArg1 != NULL ){
|
|
VARG_FREE( Commands[i].strArg1 );
|
|
}
|
|
|
|
if( Commands[i].strArg2 != NULL ){
|
|
VARG_FREE( Commands[i].strArg2 );
|
|
}
|
|
|
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
dwStatus = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
|
|
SetConsoleTextAttribute( g_hConsole, g_original );
|
|
}
|
|
|
|
void LoadCmd()
|
|
{
|
|
HRESULT hr;
|
|
int i;
|
|
TCHAR buffer[MAXSTR];
|
|
TCHAR param[MAXSTR];
|
|
|
|
i = LoadString( NULL, IDS_ARG_TOKEN, buffer, VARG_TOKEN_LEN );
|
|
if( i>0 && i <= VARG_TOKEN_LEN ){
|
|
_tcsncpy( g_strArgToken, buffer, i );
|
|
}
|
|
|
|
i = LoadString( NULL, IDS_ARG_PREFIX, buffer, VARG_ARG_PREFIX_LEN );
|
|
if( i>0 && i <= VARG_ARG_PREFIX_LEN ){
|
|
_tcsncpy( g_strPrefix, buffer, i );
|
|
}
|
|
|
|
i = LoadString( NULL, IDS_VERB_PREFIX, buffer, VARG_VERB_PREFIX_LEN );
|
|
if( i>0 && i <= VARG_VERB_PREFIX_LEN){
|
|
_tcsncpy( g_strVerbPrefix, buffer, i );
|
|
}
|
|
|
|
for( i=0; Commands[i].fType!=VARG_TYPE_LAST; i++ ){
|
|
|
|
LPTSTR strArg1;
|
|
LPTSTR strArg2;
|
|
LPTSTR strParam;
|
|
LPTSTR strHelp;
|
|
|
|
LoadString( NULL, Commands[i].idParam, param, MAXSTR );
|
|
|
|
strArg1 = _tcstok( param, g_strArgToken );
|
|
strArg2 = _tcstok( NULL, g_strArgToken );
|
|
strParam = _tcstok( NULL, g_strArgToken );
|
|
strHelp = _tcstok( NULL, g_strArgToken );
|
|
|
|
COPY_RESOURCE( Commands[i].strArg1, strArg1, _T("*") );
|
|
COPY_RESOURCE( Commands[i].strArg2, strArg2, _T("*") );
|
|
|
|
if( Commands[i].fFlag & VARG_FLAG_ARG_DATE ){
|
|
TCHAR strDate[80];
|
|
TCHAR strTime[80];
|
|
TCHAR strAM[4];
|
|
TCHAR strPM[4];
|
|
|
|
GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SSHORTDATE, strDate, 80 );
|
|
GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, strTime, 80 );
|
|
if( !GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_S1159, strAM, 4 ) ){
|
|
strAM[0] = _T('\0');
|
|
}
|
|
if( !GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_S2359, strPM, 4 ) ){
|
|
strPM[0] = _T('\0');
|
|
}
|
|
_tcstok( strTime, _T(" ") );
|
|
if( _tcslen( strAM ) && _tcslen(strPM) ){
|
|
if( Commands[i].fFlag & VARG_FLAG_DEFAULTABLE ){
|
|
hr = StringCchPrintf( buffer, MAXSTR, _T("[%s %s[%s|%s]]"), strDate, strTime, strAM, strPM );
|
|
}else{
|
|
hr = StringCchPrintf( buffer, MAXSTR, _T("<%s %s[%s|%s]>"), strDate, strTime, strAM, strPM );
|
|
}
|
|
}else{
|
|
if( Commands[i].fFlag & VARG_FLAG_DEFAULTABLE ){
|
|
hr = StringCchPrintf( buffer, MAXSTR, _T("[%s %s]"), strDate, strTime );
|
|
}else{
|
|
hr = StringCchPrintf( buffer, MAXSTR, _T("<%s %s>"), strDate, strTime );
|
|
}
|
|
}
|
|
COPY_RESOURCE( Commands[i].strParam, buffer, _T("*") );
|
|
|
|
}else{
|
|
if( Commands[i].fFlag & VARG_FLAG_ARG_DEFAULT ){
|
|
LoadString( NULL, IDS_ARG_DEFAULT, param, MAXSTR );
|
|
strParam = param;
|
|
}else if( Commands[i].fFlag & VARG_FLAG_ARG_FILENAME ){
|
|
LoadString( NULL, IDS_ARG_FILENAME, param, MAXSTR );
|
|
strParam = param;
|
|
}else if( Commands[i].fFlag & VARG_FLAG_ARG_TIME ){
|
|
LoadString( NULL, IDS_ARG_TIME, param, MAXSTR );
|
|
strParam = param;
|
|
}
|
|
if( strParam != NULL && _tcslen( strParam ) && _tcscmp( strParam, _T("*") ) ){
|
|
if( Commands[i].fFlag & VARG_FLAG_DEFAULTABLE ){
|
|
if( Commands[i].fType == VARG_TYPE_MSZ && !(Commands[i].fFlag & VARG_FLAG_FLATHELP) ){
|
|
hr = StringCchPrintf( buffer, MAXSTR, _T("[%s [%s ...]]"), strParam, strParam );
|
|
}else{
|
|
hr = StringCchPrintf( buffer, MAXSTR, _T("[%s]"), strParam );
|
|
}
|
|
}else{
|
|
if( Commands[i].fType == VARG_TYPE_MSZ && !(Commands[i].fFlag & VARG_FLAG_FLATHELP)){
|
|
hr = StringCchPrintf( buffer, MAXSTR, _T("<%s [%s ...]>"), strParam, strParam );
|
|
}else{
|
|
hr = StringCchPrintf( buffer, MAXSTR, _T("<%s>"), strParam );
|
|
}
|
|
}
|
|
COPY_RESOURCE( Commands[i].strParam, buffer, _T("*") );
|
|
}else{
|
|
strParam = NULL;
|
|
COPY_RESOURCE( Commands[i].strParam, strParam, _T("*") );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ULONG MszStrLen( LPTSTR mszBuffer )
|
|
{
|
|
ULONG nLength = 0;
|
|
ULONG nTotalLength = 0;
|
|
LPTSTR strScan = mszBuffer;
|
|
ULONG nTermSize = sizeof(TCHAR) * 2;
|
|
|
|
while( strScan != NULL && *strScan != _T('\0') ){
|
|
nLength = (_tcslen( strScan )+1);
|
|
strScan += nLength;
|
|
nTotalLength += nLength;
|
|
}
|
|
|
|
return (nTotalLength*sizeof(TCHAR) + nTermSize);
|
|
}
|
|
|
|
HRESULT
|
|
AddStringToMsz( LPTSTR* mszBuffer, LPTSTR strValue )
|
|
{
|
|
size_t cbNewDataSize = 0;
|
|
size_t cbOldDataSize = 0;
|
|
size_t cbTotalDataSize = 0;
|
|
LPTSTR strScan = *mszBuffer;
|
|
LPTSTR mszNewBuffer;
|
|
ULONG nLength;
|
|
|
|
if( IsEmpty( strValue ) ){
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
if( strScan != NULL ){
|
|
while( *strScan != _T('\0') ){
|
|
nLength = (_tcslen( strScan )+1);
|
|
strScan += nLength;
|
|
cbOldDataSize += nLength * sizeof(TCHAR);
|
|
}
|
|
}
|
|
|
|
cbNewDataSize = ( _tcslen( strValue )+1 ) * sizeof(TCHAR);
|
|
|
|
cbTotalDataSize = cbOldDataSize + cbNewDataSize + (sizeof(TCHAR)*2);
|
|
|
|
mszNewBuffer = (LPTSTR)VARG_ALLOC( cbTotalDataSize );
|
|
|
|
if( NULL == mszNewBuffer ){
|
|
return ERROR_OUTOFMEMORY;
|
|
}
|
|
|
|
ZeroMemory( mszNewBuffer, cbTotalDataSize );
|
|
|
|
if( cbOldDataSize ){
|
|
memcpy( mszNewBuffer, *mszBuffer, cbOldDataSize );
|
|
memcpy( (((PUCHAR)mszNewBuffer) + cbOldDataSize), strValue, cbNewDataSize );
|
|
|
|
//
|
|
// Zero the old memory block in case it
|
|
// contained sensitive information
|
|
//
|
|
|
|
ZeroMemory( *mszBuffer, cbOldDataSize );
|
|
|
|
}else{
|
|
memcpy( mszNewBuffer, strValue, cbNewDataSize );
|
|
}
|
|
|
|
VARG_FREE( *mszBuffer );
|
|
|
|
*mszBuffer = mszNewBuffer;
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
void ParseIni( LPTSTR strFile )
|
|
{
|
|
HRESULT hr;
|
|
TCHAR buffer[MAXSTR];
|
|
FILE* f;
|
|
LPTSTR str;
|
|
TCHAR strCmd[MAXSTR];
|
|
LPTSTR strValue;
|
|
BOOL bFound;
|
|
int i;
|
|
|
|
ZeroMemory( strCmd, MAXSTR*sizeof(TCHAR) );
|
|
|
|
if( strFile == NULL || _tcslen( strFile ) == 0 ){
|
|
return;
|
|
}
|
|
|
|
f = _tfopen( strFile, _T("r") );
|
|
if( NULL == f ){
|
|
return;
|
|
}
|
|
while( _fgetts( buffer, MAXSTR, f ) ){
|
|
|
|
if( buffer[0] == _T(';') || // comments
|
|
buffer[0] == _T('#') ){
|
|
|
|
continue;
|
|
}
|
|
|
|
Chomp( buffer );
|
|
|
|
if( IsEmpty( buffer ) ){
|
|
continue;
|
|
}
|
|
|
|
if( buffer[0] == _T('[') || _tcsstr( buffer, _T("=") ) ){
|
|
str = _tcstok( buffer, _T("[]\n\t=") );
|
|
if( str != NULL ){
|
|
hr = StringCchCopy( strCmd, MAXSTR, str );
|
|
strValue = _tcstok( NULL, _T("]=\n ") );
|
|
}else{
|
|
strCmd[0] = _T('\0');
|
|
strValue = NULL;
|
|
}
|
|
}else{
|
|
strValue = _tcstok( buffer, _T("\n") );
|
|
}
|
|
|
|
bFound = FALSE;
|
|
|
|
//
|
|
// Check to see if it is a parameter that does not take a value
|
|
//
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST && (!bFound);i++ ){
|
|
if( IsCmd( &Commands[i], strCmd, TRUE ) ){
|
|
switch( Commands[i].fType ){
|
|
case VARG_TYPE_HELP:
|
|
bFound = TRUE;
|
|
break;
|
|
case VARG_TYPE_BOOL:
|
|
bFound = TRUE;
|
|
Commands[i].bValue = Commands[i].bValue ? FALSE : TRUE;
|
|
break;
|
|
}
|
|
if( bFound ){
|
|
Commands[i].bDefined = TRUE;
|
|
|
|
if( Commands[i].bDefined && Commands[i].fntValidation != NULL ){
|
|
Commands[i].fntValidation(i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( bFound || strValue == NULL || _tcslen( strCmd ) == 0 ){
|
|
continue;
|
|
}
|
|
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST && (!bFound);i++ ){
|
|
if( IsCmd( &Commands[i], strCmd, TRUE ) ){
|
|
|
|
bFound = TRUE;
|
|
if( Commands[i].bDefined && Commands[i].fType != VARG_TYPE_MSZ ){
|
|
continue;
|
|
}
|
|
|
|
switch( Commands[i].fType ){
|
|
case VARG_TYPE_DEBUG:
|
|
case VARG_TYPE_INT:
|
|
{
|
|
ULONG nValue;
|
|
if( ERROR_SUCCESS == ReadLong( strValue, &nValue, MAXLONG ) ){
|
|
Commands[i].nValue = nValue;
|
|
if( Commands[i].fType == VARG_TYPE_DEBUG ){
|
|
g_nDebug = nValue;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case VARG_TYPE_MSZ:
|
|
if( !Commands[i].bDefined ){
|
|
Commands[i].strValue = NULL;
|
|
}
|
|
if( Commands[i].fFlag & VARG_FLAG_CHOMP ){
|
|
Chomp( strValue );
|
|
}
|
|
varg_cmdStringAddMsz( i, strValue );
|
|
break;
|
|
case VARG_TYPE_STR:
|
|
if( Commands[i].fFlag & VARG_FLAG_CHOMP ){
|
|
Chomp( strValue );
|
|
}
|
|
varg_cmdStringAssign( i, strValue );
|
|
break;
|
|
case VARG_TYPE_TIME:
|
|
case VARG_TYPE_DATE:
|
|
ParseTime( strValue, &Commands[i].stValue, (Commands[i].fType == VARG_TYPE_DATE) );
|
|
break;
|
|
}
|
|
|
|
Commands[i].bDefined = TRUE;
|
|
|
|
if( Commands[i].bDefined && Commands[i].fntValidation != NULL ){
|
|
Commands[i].fntValidation(i);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose(f);
|
|
}
|
|
|
|
void ParseCmd(int argc, LPTSTR argv[] )
|
|
{
|
|
int i;
|
|
BOOL bFound;
|
|
BOOL bHelp = FALSE;
|
|
BOOL bBadSyntax = FALSE;
|
|
|
|
int nIniIndex = (-1);
|
|
|
|
VSetThreadUILanguage(0);
|
|
|
|
VArgDeclareFormat();
|
|
LoadCmd();
|
|
SetUpColors();
|
|
|
|
g_strProg = argv[0];
|
|
argv++;argc--;
|
|
|
|
while( argc > 0 ){
|
|
|
|
bFound = FALSE;
|
|
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST && (!bFound);i++){
|
|
|
|
if( IsCmd( &Commands[i], argv[0], FALSE ) ){
|
|
|
|
if(Commands[i].bDefined){
|
|
PrintMessage( g_debug, IDS_MESSAGE_ARG_DUP, Commands[i].strArg1, argv[0] );
|
|
bBadSyntax = TRUE;
|
|
}
|
|
|
|
if( IsArg( argv[0] ) || Commands[i].fFlag & VARG_FLAG_VERB || Commands[i].fFlag & VARG_FLAG_ADVERB ){
|
|
argv++;argc--;
|
|
}
|
|
|
|
bFound = TRUE;
|
|
|
|
Commands[i].bDefined = TRUE;
|
|
|
|
switch( Commands[i].fType ){
|
|
case VARG_TYPE_HELP:
|
|
Commands[i].bValue = TRUE;
|
|
bHelp = TRUE;
|
|
break;
|
|
case VARG_TYPE_DEBUG:
|
|
Commands[i].fFlag |= VARG_FLAG_DEFAULTABLE;
|
|
g_nDebug = Commands[i].nValue;
|
|
case VARG_TYPE_INT:
|
|
if( argc > 0 && !IsArg( argv[0] ) ){
|
|
ULONG nValue;
|
|
HRESULT hr = ReadLong( argv[0], &nValue, MAXLONG );
|
|
if( ERROR_SUCCESS == hr ){
|
|
Commands[i].nValue = nValue;
|
|
}else{
|
|
Commands[i].fFlag |= VARG_FLAG_BADSYNTAX;
|
|
}
|
|
if( Commands[i].fType == VARG_TYPE_DEBUG ){
|
|
g_nDebug = Commands[i].nValue;
|
|
}
|
|
argv++;argc--;
|
|
}else if( !(Commands[i].fFlag & VARG_FLAG_DEFAULTABLE) ){
|
|
if( !Commands[i].bNegated ){
|
|
Commands[i].fFlag |= VARG_FLAG_BADSYNTAX;
|
|
}
|
|
}
|
|
break;
|
|
case VARG_TYPE_BOOL:
|
|
Commands[i].bValue = Commands[i].bValue ? FALSE : TRUE;
|
|
break;
|
|
case VARG_TYPE_MSZ:
|
|
if( argc > 0 && !IsArg( argv[0] ) ){
|
|
Commands[i].fFlag &= ~VARG_FLAG_RCDEFAULT;
|
|
varg_cmdStringAssign( i, argv[0] );
|
|
OOM( Commands[i].strValue );
|
|
argv++;argc--;
|
|
while( argc > 0 && ! IsArg( argv[0] ) ){
|
|
if( Commands[i].fFlag & VARG_FLAG_CHOMP ){
|
|
Chomp( argv[0] );
|
|
}
|
|
varg_cmdStringAddMsz( i, argv[0] );
|
|
argv++;argc--;
|
|
}
|
|
}else if( Commands[i].fFlag & VARG_FLAG_DEFAULTABLE || Commands[i].bNegated ){
|
|
Commands[i].fFlag |= VARG_FLAG_DODEFAULT;
|
|
}else{
|
|
Commands[i].fFlag |= VARG_FLAG_BADSYNTAX;
|
|
}
|
|
break;
|
|
case VARG_TYPE_INI:
|
|
nIniIndex = i;
|
|
case VARG_TYPE_STR:
|
|
if( argc > 0 && ! IsArg( argv[0] ) ){
|
|
if( Commands[i].fFlag & VARG_FLAG_CHOMP ){
|
|
Chomp( argv[0] );
|
|
}
|
|
Commands[i].fFlag &= ~VARG_FLAG_RCDEFAULT;
|
|
varg_cmdStringAssign( i, argv[0] );
|
|
argv++;argc--;
|
|
}else if( Commands[i].fFlag & VARG_FLAG_DEFAULTABLE || Commands[i].bNegated ){
|
|
Commands[i].fFlag |= VARG_FLAG_DODEFAULT;
|
|
}else{
|
|
if( !(Commands[i].fFlag & VARG_FLAG_NEGATE) ){
|
|
Commands[i].fFlag |= VARG_FLAG_BADSYNTAX;
|
|
}
|
|
}
|
|
break;
|
|
case VARG_TYPE_TIME:
|
|
case VARG_TYPE_DATE:
|
|
if( argc > 0 && !IsArg( argv[0] ) ){
|
|
HRESULT hr;
|
|
LPTSTR strDate = NULL;
|
|
LPTSTR strTime = argv[0];
|
|
argv++;argc--;
|
|
if( Commands[i].fType == VARG_TYPE_DATE ){
|
|
if( argc > 0 && !IsArg( argv[0] ) ){
|
|
size_t cbSize = (_tcslen(strTime)+_tcslen(argv[0])+2)*sizeof(TCHAR);
|
|
|
|
strDate = (LPTSTR)VARG_ALLOC( cbSize );
|
|
if( NULL != strDate ){
|
|
hr = StringCbPrintf( strDate, cbSize, _T("%s %s"), strTime, argv[0] );
|
|
strTime = strDate;
|
|
}
|
|
argv++;argc--;
|
|
}
|
|
}
|
|
|
|
hr = ParseTime( strTime, &Commands[i].stValue, (Commands[i].fType == VARG_TYPE_DATE) );
|
|
if( ERROR_SUCCESS != hr ){
|
|
Commands[i].fFlag |= VARG_FLAG_BADSYNTAX;
|
|
}
|
|
VARG_FREE( strDate );
|
|
}else if( !(Commands[i].fFlag & VARG_FLAG_DEFAULTABLE) && !(Commands[i].bNegated) ){
|
|
Commands[i].fFlag |= VARG_FLAG_BADSYNTAX;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bFound){
|
|
PrintMessage( g_debug, IDS_MESSAGE_UNKNOWNPARAM, (*(argv)));
|
|
argv++;argc--;
|
|
bBadSyntax = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
if( nIniIndex >= 0 ){
|
|
if( Commands[nIniIndex].fType == VARG_TYPE_INI && Commands[nIniIndex].bDefined ){
|
|
ParseIni( Commands[nIniIndex].strValue );
|
|
}
|
|
}
|
|
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST;i++){
|
|
|
|
if( !bHelp && (Commands[i].bDefined && Commands[i].fntValidation != NULL ) ){
|
|
Commands[i].fntValidation(i);
|
|
}
|
|
|
|
if( Commands[i].fFlag & VARG_FLAG_RCDEFAULT ||
|
|
(( Commands[i].fType == VARG_TYPE_STR ||
|
|
Commands[i].fType == VARG_TYPE_MSZ ||
|
|
Commands[i].fType == VARG_TYPE_INI ) &&
|
|
(!Commands[i].bDefined || Commands[i].fFlag & VARG_FLAG_DODEFAULT )) ){
|
|
|
|
TCHAR buffer[MAXSTR];
|
|
|
|
Commands[i].fFlag &= ~VARG_FLAG_DODEFAULT;
|
|
if( Commands[i].fFlag & VARG_FLAG_RCDEFAULT ){
|
|
LoadString( NULL, Commands[i].nValue, buffer, MAXSTR );
|
|
varg_cmdStringAssign( i, buffer );
|
|
OOM( Commands[i].strValue );
|
|
}
|
|
}
|
|
|
|
if( Commands[i].bDefined && Commands[i].fFlag & VARG_FLAG_EXPANDFILES ){
|
|
Commands[i].fFlag |= VARG_FLAG_ALLOCSTR;
|
|
ExpandFiles( &Commands[i].strValue, (Commands[i].fType == VARG_TYPE_MSZ) );
|
|
}
|
|
|
|
}
|
|
|
|
if( bHelp ){
|
|
DisplayCommandLineHelp();
|
|
}
|
|
|
|
if( g_nDebug >= 0 ){
|
|
DisplayDebugInfo();
|
|
}
|
|
|
|
if( ERROR_SUCCESS != ValidateCommands() || bBadSyntax ){
|
|
PrintMessage( g_debug, IDS_MESSAGE_INCORRECT );
|
|
FreeCmd();
|
|
exit(ERROR_BAD_FORMAT);
|
|
}
|
|
}
|
|
|
|
void
|
|
DisplayIniInfo()
|
|
{
|
|
int i;
|
|
int nOut;
|
|
BOOL bOpt;
|
|
PrintMessage( g_normal, IDS_MESSAGE_INISYNT );
|
|
for( i=0;i<35;i++){ varg_printf( g_normal, _T("-") ); }
|
|
varg_printf( g_normal, _T("\n") );
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST;i++){
|
|
|
|
if( Commands[i].fFlag & VARG_FLAG_HIDDEN && !(Commands[i].bDefined) ){
|
|
continue;
|
|
}
|
|
|
|
bOpt = ( Commands[i].strArg2 != NULL && _tcslen( Commands[i].strArg2 ) );
|
|
|
|
switch( Commands[i].fType ){
|
|
case VARG_TYPE_DEBUG:
|
|
case VARG_TYPE_BOOL:
|
|
case VARG_TYPE_MSZ:
|
|
case VARG_TYPE_STR:
|
|
case VARG_TYPE_INT:
|
|
case VARG_TYPE_TIME:
|
|
case VARG_TYPE_DATE:
|
|
nOut = varg_printf( g_normal,
|
|
_T(" %1!-20s! %2!-20s!\n"),
|
|
Commands[i].strArg1, bOpt ?
|
|
Commands[i].strArg2 : _T("")
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
varg_printf( g_normal, _T("\n") );
|
|
}
|
|
|
|
void
|
|
DisplayDebugInfo()
|
|
{
|
|
int i;
|
|
int nOut;
|
|
TCHAR strDefault[MAXSTR] = _T("");
|
|
|
|
LoadString( NULL, IDS_MESSAGE_DEFAULT, strDefault, MAXSTR );
|
|
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST;i++){
|
|
if( !(Commands[i].bDefined) && g_nDebug < 1 ){
|
|
continue;
|
|
}
|
|
if( Commands[i].fType == VARG_TYPE_HELP ){
|
|
continue;
|
|
}
|
|
if( Commands[i].fFlag & VARG_FLAG_HIDDEN && !(Commands[i].bDefined) ){
|
|
continue;
|
|
}
|
|
nOut = varg_printf( g_debug, _T("%1!-16s! = "), Commands[i].strArg1 );
|
|
switch( Commands[i].fType ){
|
|
case VARG_TYPE_DEBUG:
|
|
case VARG_TYPE_INT:
|
|
varg_printf( g_debug, _T("%1!-20lu!"), Commands[i].nValue );
|
|
break;
|
|
case VARG_TYPE_BOOL:
|
|
varg_printf( g_debug, _T("%1!-20s!"),
|
|
Commands[i].bValue ? _T("TRUE") : _T("FALSE")
|
|
);
|
|
break;
|
|
case VARG_TYPE_MSZ:
|
|
if( !IsEmpty( Commands[i].strValue ) ){
|
|
LPTSTR strValue = Commands[i].strValue;
|
|
while( *strValue != _T('\0') ){
|
|
if( strValue == Commands[i].strValue ){
|
|
varg_printf( g_debug, _T("%1!-20s!"), strValue );
|
|
}else{
|
|
varg_printf( g_debug, _T("\n%1!19s!%2!-20s!"), _T(" "), strValue );
|
|
}
|
|
strValue += (_tcslen( strValue )+1);
|
|
}
|
|
}else{
|
|
varg_printf( g_debug, _T("%1!-20s!"), _T("-") );
|
|
}
|
|
break;
|
|
case VARG_TYPE_TIME:
|
|
case VARG_TYPE_DATE:
|
|
{
|
|
nOut = PrintDateEx( g_debug, &Commands[i].stValue );
|
|
while( nOut++ < 20 ) { varg_printf( g_debug, _T(" ") ); }
|
|
}
|
|
break;
|
|
case VARG_TYPE_INI:
|
|
case VARG_TYPE_STR:
|
|
varg_printf( g_debug, _T("%1!-20s!"),
|
|
(Commands[i].strValue == NULL || !(_tcslen(Commands[i].strValue)) ) ?
|
|
_T("-") : Commands[i].strValue
|
|
);
|
|
break;
|
|
}
|
|
if( !Commands[i].bDefined ){
|
|
varg_printf( g_debug, _T(" (%1!s!)"), strDefault );
|
|
}
|
|
varg_printf( g_debug, _T("\n") );
|
|
|
|
}
|
|
varg_printf( g_debug, _T("\n") );
|
|
}
|
|
|
|
int PrintMessage( WORD color, LONG id, ... )
|
|
{
|
|
int nLoad;
|
|
TCHAR buffer[MAXSTR];
|
|
va_list args;
|
|
|
|
va_start( args, id );
|
|
|
|
nLoad = LoadString( NULL, id, buffer, MAXSTR );
|
|
|
|
if( nLoad > 0 ){
|
|
nLoad = varg_vprintf( color, buffer, args );
|
|
}else{
|
|
nLoad = FormatMessage(
|
|
FORMAT_MESSAGE_FROM_HMODULE,
|
|
GetModuleHandle(NULL),
|
|
id,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
buffer,
|
|
MAXSTR,
|
|
&args
|
|
);
|
|
varg_printf( color, buffer );
|
|
}
|
|
|
|
return nLoad;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
|
|
IsFullWidth
|
|
|
|
Determine if the given Unicode char is fullwidth or not.
|
|
|
|
|
|
04-08-1992 ShunK Created.
|
|
|
|
07-11-1995 FloydR Modified to be Japanese aware, when enabled for
|
|
other DBCS languages. Note that we could build
|
|
KOREA/TAIWAN/PRC w/o this code, but we like single
|
|
binary solutions.
|
|
|
|
10-06-1996 KazuM Not use RtlUnicodeToMultiByteSize and
|
|
WideCharToMultiByte because 950 only defined
|
|
13500 chars, and unicode defined almost 18000 chars.
|
|
So there are almost 4000 chars can not be mapped to
|
|
big5 code.
|
|
|
|
07-27-2001 CoreyM Stolen from base\cmd for string wrapping
|
|
|
|
\***************************************************************************/
|
|
|
|
BOOL IsFullWidth(TCHAR wch)
|
|
{
|
|
if (0x20 <= wch && wch <= 0x7e)
|
|
/* ASCII */
|
|
return FALSE;
|
|
else if (0x3000 <= wch && wch <= 0x3036)
|
|
/* CJK Symbols and Punctuation */
|
|
return TRUE;
|
|
else if (0x3041 <= wch && wch <= 0x3094)
|
|
/* Hiragana */
|
|
return TRUE;
|
|
else if (0x30a1 <= wch && wch <= 0x30fe)
|
|
/* Katakana */
|
|
return TRUE;
|
|
else if (0x3105 <= wch && wch <= 0x312c)
|
|
/* Bopomofo */
|
|
return TRUE;
|
|
else if (0x3131 <= wch && wch <= 0x318e)
|
|
/* Hangul Elements */
|
|
return TRUE;
|
|
else if (0x3200 <= wch && wch <= 0x32ff)
|
|
/* Enclosed CJK Letters and Ideographics */
|
|
return TRUE;
|
|
else if (0x3300 <= wch && wch <= 0x33fe)
|
|
/* CJK Squared Words and Abbreviations */
|
|
return TRUE;
|
|
else if (0xac00 <= wch && wch <= 0xd7a3)
|
|
/* Korean Hangul Syllables */
|
|
return TRUE;
|
|
else if (0xe000 <= wch && wch <= 0xf8ff)
|
|
/* EUDC */
|
|
return TRUE;
|
|
else if (0xff01 <= wch && wch <= 0xff5e)
|
|
/* Fullwidth ASCII variants */
|
|
return TRUE;
|
|
else if (0xff61 <= wch && wch <= 0xff9f)
|
|
/* Halfwidth Katakana variants */
|
|
return FALSE;
|
|
else if ( (0xffa0 <= wch && wch <= 0xffbe) ||
|
|
(0xffc2 <= wch && wch <= 0xffc7) ||
|
|
(0xffca <= wch && wch <= 0xffcf) ||
|
|
(0xffd2 <= wch && wch <= 0xffd7) ||
|
|
(0xffda <= wch && wch <= 0xffdc) )
|
|
/* Halfwidth Hangule variants */
|
|
return FALSE;
|
|
else if (0xffe0 <= wch && wch <= 0xffe6)
|
|
/* Fullwidth symbol variants */
|
|
return TRUE;
|
|
else if (0x4e00 <= wch && wch <= 0x9fa5)
|
|
/* CJK Ideographic */
|
|
return TRUE;
|
|
else if (0xf900 <= wch && wch <= 0xfa2d)
|
|
/* CJK Compatibility Ideographs */
|
|
return TRUE;
|
|
else if (0xfe30 <= wch && wch <= 0xfe4f) {
|
|
/* CJK Compatibility Forms */
|
|
return TRUE;
|
|
}
|
|
|
|
else
|
|
/* Unknown character */
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
varg_strlen( LPTSTR str, ULONG* pVisualLength, ULONG* pActualLength )
|
|
{
|
|
ULONG nVisual = 0;
|
|
ULONG nActual = 0;
|
|
|
|
if( NULL != str ){
|
|
nActual = _tcslen(str);
|
|
|
|
if( NULL != pVisualLength && IsDBCSCodePage() ){
|
|
while (*str) {
|
|
if (IsFullWidth(*str)){
|
|
nVisual += 2;
|
|
}else{
|
|
nVisual++;
|
|
}
|
|
str++;
|
|
}
|
|
}else{
|
|
nVisual = nActual;
|
|
}
|
|
|
|
if( NULL != pVisualLength ){
|
|
*pVisualLength = nVisual;
|
|
}
|
|
|
|
if( NULL != pActualLength ){
|
|
*pActualLength = nActual;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL WrapString( LPTSTR str, ULONG nCol, ULONG* pBreak )
|
|
{
|
|
ULONG nVisual = 0;
|
|
ULONG nActual = 0;
|
|
ULONG nBreak = 0;
|
|
|
|
*pBreak = 0;
|
|
|
|
while( *str ){
|
|
nActual++;
|
|
if( IsFullWidth( *str ) ){
|
|
nVisual += 2;
|
|
if( nVisual < nCol ){
|
|
nBreak = nActual;
|
|
}
|
|
}else{
|
|
nVisual++;
|
|
if( nVisual < nCol ){
|
|
if( IsCharWhitespace( *str ) ){
|
|
nBreak = nActual-1;
|
|
if( *str == _T('\n') ){
|
|
*pBreak = nBreak;
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if( nVisual > nCol ){
|
|
if( nBreak ){
|
|
*pBreak = nBreak;
|
|
return TRUE;
|
|
}else{
|
|
return FALSE;
|
|
}
|
|
}
|
|
str++;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void SetColumn( LONG nStart, LONG nCol )
|
|
{
|
|
while( nStart++ < nCol ){
|
|
varg_printf( g_normal, _T(" ") );
|
|
}
|
|
}
|
|
|
|
HRESULT PrintHelpString( LONG id, LONG nStart, LONG nCol, LONG nMax, BOOL bSwitch )
|
|
{
|
|
int nLoad;
|
|
TCHAR buffer[MAXSTR];
|
|
LPTSTR strHelp;
|
|
ULONG nWrap;
|
|
|
|
nMax -= (nMax%2);
|
|
|
|
if( nMax <= nCol ){
|
|
nMax = 79;
|
|
}
|
|
|
|
nLoad = LoadString( NULL, id, buffer, MAXSTR );
|
|
strHelp = _tcstok( buffer, g_strArgToken );
|
|
|
|
if( bSwitch ){
|
|
_tcstok( NULL, g_strArgToken );
|
|
_tcstok( NULL, g_strArgToken );
|
|
strHelp = _tcstok( NULL, g_strArgToken );
|
|
}
|
|
|
|
if( nStart < nCol ){
|
|
SetColumn( nStart, nCol );
|
|
nWrap = nMax - nCol;
|
|
}else{
|
|
nWrap = nMax - nStart;
|
|
}
|
|
|
|
if( nLoad > 0 && strHelp != NULL && _tcslen( strHelp ) ){
|
|
|
|
LPTSTR str;
|
|
ULONG nBreak;
|
|
TCHAR cWrap;
|
|
str = strHelp;
|
|
|
|
while( *str != _T('\0') ){
|
|
if( WrapString( str, nWrap, &nBreak ) ){
|
|
cWrap = str[nBreak];
|
|
str[nBreak] = _T('\0');
|
|
varg_printf( g_normal, str );
|
|
str[nBreak] = cWrap;
|
|
str += nBreak;
|
|
if( IsCharWhitespace( *str ) ){
|
|
str++;
|
|
}
|
|
varg_printf( g_normal, _T("\n") );
|
|
SetColumn( 0, nCol );
|
|
nWrap = nMax - nCol;
|
|
}else{
|
|
varg_printf( g_normal, str );
|
|
varg_printf( g_normal, _T("\n") );
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
|
}
|
|
|
|
void DisplayVersionInfo()
|
|
{
|
|
HRESULT hr;
|
|
TCHAR buffer[512];
|
|
TCHAR strProgram[MAXSTR];
|
|
TCHAR strMicrosoft[512];
|
|
DWORD dw;
|
|
BYTE* pVersionInfo;
|
|
LPTSTR pVersion = NULL;
|
|
LPTSTR pProduct = NULL;
|
|
LPTSTR pCopyRight = NULL;
|
|
|
|
dw = GetModuleFileName(NULL, strProgram, MAXSTR );
|
|
LoadString( NULL, IDS_MESSAGE_MSR, strMicrosoft, 512 );
|
|
|
|
if( dw>0 ){
|
|
|
|
dw = GetFileVersionInfoSize( strProgram, &dw );
|
|
if( dw > 0 ){
|
|
|
|
pVersionInfo = (BYTE*)VARG_ALLOC(dw);
|
|
if( NULL != pVersionInfo ){
|
|
if(GetFileVersionInfo( strProgram, 0, dw, pVersionInfo )){
|
|
LPDWORD lptr = NULL;
|
|
VerQueryValue( pVersionInfo, _T("\\VarFileInfo\\Translation"), (void**)&lptr, (UINT*)&dw );
|
|
if( lptr != NULL ){
|
|
hr = StringCchPrintf( buffer, 512, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("ProductVersion") );
|
|
VerQueryValue( pVersionInfo, buffer, (void**)&pVersion, (UINT*)&dw );
|
|
hr = StringCchPrintf( buffer, 512, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("OriginalFilename") );
|
|
VerQueryValue( pVersionInfo, buffer, (void**)&pProduct, (UINT*)&dw );
|
|
hr = StringCchPrintf( buffer, 512, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("LegalCopyright") );
|
|
VerQueryValue( pVersionInfo, buffer, (void**)&pCopyRight, (UINT*)&dw );
|
|
}
|
|
|
|
if( pProduct != NULL && pVersion != NULL && pCopyRight != NULL ){
|
|
varg_printf( g_normal, _T("\n%1!s! %2!s! (%3!s!)\n%4!s!\n\n"), strMicrosoft, pProduct, pVersion, pCopyRight );
|
|
}
|
|
}
|
|
VARG_FREE( pVersionInfo );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
DisplayHelpEx( LONG id )
|
|
{
|
|
TCHAR buffer[8];
|
|
DWORD dwSize = 8;
|
|
|
|
dwSize = LoadString( NULL, id, buffer, dwSize );
|
|
if( dwSize > 0 ){
|
|
PrintMessage( g_normal, id );
|
|
}
|
|
}
|
|
|
|
void
|
|
DisplayCommandLineHelp()
|
|
{
|
|
int i,j;
|
|
int nOut;
|
|
BOOL bOpt;
|
|
BOOL bVerbs = FALSE;
|
|
int nVerbs = 0;
|
|
int nCommands = 0;
|
|
BOOL bRequired = FALSE;
|
|
int nConditional = 0;
|
|
int nDefinedConditional = 0;
|
|
BOOL bFirst = TRUE;
|
|
BOOL bDisplayAll = FALSE;
|
|
DWORD dwVerbMask = 0;
|
|
UCHAR excl1 = 0;
|
|
LPTSTR strNegateHelp = NULL;
|
|
|
|
for( i=0; Commands[i].fType != VARG_TYPE_LAST;i++){
|
|
if( (Commands[i].dwSet & VARG_CONDITION) &&
|
|
!(Commands[i].fFlag & VARG_FLAG_VERB) ){
|
|
nConditional++;
|
|
if( Commands[i].bDefined ){
|
|
nDefinedConditional++;
|
|
}
|
|
}
|
|
if( Commands[i].fFlag & VARG_FLAG_VERB ){
|
|
bVerbs = TRUE;
|
|
}
|
|
|
|
if( Commands[i].bDefined ){
|
|
if( Commands[i].fFlag & VARG_FLAG_VERB || Commands[i].fFlag & VARG_FLAG_ADVERB){
|
|
nVerbs++;
|
|
dwVerbMask |= (Commands[i].dwVerb & 0x0000FFFF);
|
|
if( Commands[i].dwSet != 0 ){
|
|
excl1 = (UCHAR)(((Commands[i].dwSet & VARG_GROUPEXCL) >> 24) & 0x0F);
|
|
}
|
|
}else{
|
|
if( Commands[i].fType != VARG_TYPE_HELP &&
|
|
Commands[i].fType != VARG_TYPE_DEBUG ){
|
|
nCommands++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if( nCommands == 0 && nVerbs == 0 ){
|
|
bDisplayAll = TRUE;
|
|
}
|
|
DisplayVersionInfo();
|
|
|
|
if( bDisplayAll ){
|
|
if( ERROR_SUCCESS == PrintHelpString( IDS_PROGRAM_DESCRIPTION, 0, 0, g_X, FALSE ) ){
|
|
varg_printf( g_normal, _T("\n") );
|
|
}
|
|
}
|
|
|
|
// Usage
|
|
PrintMessage( g_normal, IDS_MESSAGE_USAGE );
|
|
nOut = varg_printf( g_normal, _T("%1!s! "), g_strProg );
|
|
if( bVerbs ){
|
|
LONG nDispVerbs = 0;
|
|
if( !bDisplayAll ){
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST;i++){
|
|
if( Commands[i].fFlag & VARG_FLAG_VERB && Commands[i].bDefined ){
|
|
nOut += varg_printf( g_normal, _T("%1!s! "), Commands[i].strArg1 );
|
|
nDispVerbs++;
|
|
}
|
|
}
|
|
}
|
|
if( bDisplayAll || !nDispVerbs ){
|
|
nOut += PrintMessage( g_normal, IDS_MESSAGE_VERB );
|
|
}
|
|
}
|
|
if( nConditional > 1 && nDefinedConditional == 0 ){
|
|
nOut += varg_printf( g_normal, _T("{ ") );
|
|
}
|
|
for( j=0;j<2;j++){
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST;i++){
|
|
if( j==0 ){
|
|
// show conditional switches
|
|
if( Commands[i].fFlag & VARG_FLAG_HIDDEN ||
|
|
Commands[i].fFlag & VARG_FLAG_VERB ||
|
|
!(Commands[i].dwSet & VARG_CONDITION) ){
|
|
continue;
|
|
}
|
|
if( nDefinedConditional > 0 && !Commands[i].bDefined ){
|
|
continue;
|
|
}
|
|
}else{
|
|
// show required switches
|
|
if( Commands[i].fFlag & VARG_FLAG_HIDDEN ||
|
|
Commands[i].fFlag & VARG_FLAG_VERB ||
|
|
Commands[i].dwSet & VARG_CONDITION ||
|
|
Commands[i].fFlag & VARG_FLAG_OPTIONAL ){
|
|
continue;
|
|
}
|
|
}
|
|
if( (!bFirst) && nConditional && nDefinedConditional == 0 ){
|
|
nOut += varg_printf( g_normal, _T("| ") );
|
|
}
|
|
bFirst = FALSE;
|
|
if( Commands[i].fFlag & VARG_FLAG_NOFLAG ){
|
|
nOut += varg_printf( g_normal, _T("%1!s! "), Commands[i].strParam );
|
|
}else{
|
|
nOut += varg_printf( g_normal, _T("%1!c!%2!s!%3!s!%4!s!%5!s! "),
|
|
Commands[i].fFlag&VARG_FLAG_VERB ? g_strVerbPrefix[0] : g_strPrefix[0],
|
|
Commands[i].fFlag&VARG_FLAG_NEGATE ? _T("[-]"):_T(""),
|
|
Commands[i].strArg2,
|
|
ArgExpected( &Commands[i] ) ? _T(" "): _T(""),
|
|
Commands[i].strParam
|
|
);
|
|
}
|
|
if( nOut > (g_X - 15) ){
|
|
nOut = 0;
|
|
varg_printf( g_normal, _T("\n") );
|
|
while( nOut++ < HELP_INDENT){ varg_printf( g_normal, _T(" ") ); }
|
|
}
|
|
}
|
|
if( j == 0 && (nConditional>1) && nDefinedConditional == 0 ){
|
|
varg_printf( g_normal, _T("} ") );
|
|
}
|
|
}
|
|
PrintMessage( g_normal, IDS_MESSAGE_LINEOPT );
|
|
|
|
// Verbs
|
|
if( bVerbs ){
|
|
bFirst = TRUE;
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST;i++){
|
|
if( Commands[i].fFlag & VARG_FLAG_HIDDEN && !(Commands[i].bDefined) ){
|
|
continue;
|
|
}
|
|
if( !(Commands[i].fFlag & VARG_FLAG_VERB ) ){
|
|
continue;
|
|
}
|
|
if( !bDisplayAll && !Commands[i].bDefined ){
|
|
continue;
|
|
}
|
|
if( bFirst ){
|
|
PrintMessage( g_normal, IDS_MESSAGE_VERBS );
|
|
bFirst = FALSE;
|
|
}
|
|
bOpt = ( Commands[i].strArg2 != NULL && _tcslen( Commands[i].strArg2 ) );
|
|
nOut = varg_printf( COLORIZE(i), _T(" %1!s!%2!s! %3!s! "),
|
|
g_strVerbPrefix,
|
|
(LPTSTR)(bOpt ? Commands[i].strArg2 : Commands[i].strArg1),
|
|
Commands[i].strParam
|
|
);
|
|
if( nOut > HELP_INDENT ){
|
|
nOut += varg_printf( g_normal, _T(" ") );
|
|
}
|
|
|
|
PrintHelpString( Commands[i].idParam, nOut, HELP_INDENT, g_X, TRUE );
|
|
}
|
|
if( !bFirst ){
|
|
varg_printf( g_normal, _T("\n") );
|
|
}
|
|
}
|
|
|
|
// Options
|
|
for(j=0;j<2;j++){
|
|
bFirst = TRUE;
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST;i++){
|
|
if( j==0 ){
|
|
if( !(Commands[i].fFlag & VARG_FLAG_NOFLAG) ||
|
|
Commands[i].fFlag & (VARG_FLAG_VERB|VARG_FLAG_ADVERB) ){
|
|
continue;
|
|
}
|
|
}else{
|
|
if( Commands[i].fFlag & VARG_FLAG_NOFLAG ||
|
|
Commands[i].fFlag & (VARG_FLAG_VERB|VARG_FLAG_ADVERB) ){
|
|
continue;
|
|
}
|
|
}
|
|
if( ! bDisplayAll && (Commands[i].fType == VARG_TYPE_HELP) ){
|
|
continue;
|
|
}
|
|
if( Commands[i].fFlag & VARG_FLAG_HIDDEN && !(Commands[i].bDefined) ){
|
|
continue;
|
|
}
|
|
if( bDisplayAll ||
|
|
Commands[i].bDefined ||
|
|
(((Commands[i].dwVerb & 0x0000FFFF)& dwVerbMask) && nCommands < 1 ) ){
|
|
UCHAR excl2 = (UCHAR)((((Commands[i].dwSet & VARG_GROUPEXCL) >> 24) & 0xF0) >> 4 );
|
|
if( excl2 & excl1 ){
|
|
continue;
|
|
}
|
|
if( bFirst ){
|
|
switch( j ){
|
|
case 0:
|
|
PrintMessage( g_normal, IDS_MESSAGE_PARAMETERS );
|
|
bRequired = TRUE;
|
|
break;
|
|
case 1:
|
|
PrintMessage( g_normal, IDS_MESSAGE_OPTIONS, bRequired ? _T("\n") : _T("") );
|
|
break;
|
|
}
|
|
bFirst = FALSE;
|
|
}
|
|
bOpt = ( Commands[i].strArg2 != NULL && _tcslen( Commands[i].strArg2 ) );
|
|
if( Commands[i].fFlag & VARG_FLAG_NOFLAG ){
|
|
nOut = varg_printf( COLORIZE(i), _T(" %1!s! "),
|
|
Commands[i].strParam
|
|
);
|
|
}else{
|
|
nOut = varg_printf( COLORIZE(i), _T(" %1!c!%2!s!%3!s! %4!s! "),
|
|
g_strPrefix[0],
|
|
Commands[i].fFlag & VARG_FLAG_NEGATE ? _T("[-]") : _T(""),
|
|
bOpt ? Commands[i].strArg2 : Commands[i].strArg1,
|
|
Commands[i].strParam
|
|
);
|
|
}
|
|
if( nOut > HELP_INDENT ){
|
|
nOut += varg_printf( g_normal, _T(" ") );
|
|
}
|
|
if( Commands[i].fFlag & VARG_FLAG_NEGATE && NULL == strNegateHelp ){
|
|
strNegateHelp = bOpt ? Commands[i].strArg2 : Commands[i].strArg1;
|
|
}
|
|
PrintHelpString( Commands[i].idParam, nOut, HELP_INDENT, g_X, TRUE );
|
|
if( !bDisplayAll ){
|
|
if( Commands[i].fType == VARG_TYPE_INI ){
|
|
DisplayIniInfo();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( NULL != strNegateHelp ){
|
|
PrintMessage( g_normal, IDS_MESSAGE_NEGATE, strNegateHelp, strNegateHelp );
|
|
}
|
|
|
|
// Notes
|
|
if( bDisplayAll ){
|
|
PrintMessage( g_normal, IDS_MESSAGE_HELPTEXT );
|
|
}
|
|
|
|
// Examples
|
|
bFirst = TRUE;
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST;i++){
|
|
if( bDisplayAll || Commands[i].bDefined ){
|
|
if( (bDisplayAll && bVerbs ) &&
|
|
!(Commands[i].fFlag & (VARG_FLAG_VERB|VARG_FLAG_ADVERB) ) ){
|
|
continue;
|
|
}
|
|
if( Commands[i].fFlag & VARG_FLAG_EXHELP ){
|
|
if( bFirst ){
|
|
PrintMessage( g_normal, IDS_MESSAGE_EXAMPLES );
|
|
bFirst = FALSE;
|
|
}
|
|
PrintHelpString( Commands[i].idExHelp, 0, 2, 80, FALSE );
|
|
}
|
|
}
|
|
}
|
|
|
|
FreeCmd();
|
|
exit(0);
|
|
}
|
|
|
|
void PrintParam( int idPrompt, int cmd, BOOL bEOL )
|
|
{
|
|
BOOL bUseArg1;
|
|
TCHAR buffer[MAXSTR];
|
|
bUseArg1 = (Commands[cmd].fFlag & VARG_FLAG_VERB) ||
|
|
(Commands[cmd].fFlag & VARG_FLAG_ADVERB) ||
|
|
( IsEmpty( Commands[cmd].strArg2 ) );
|
|
|
|
if( 0 != idPrompt ){
|
|
LoadString( NULL, idPrompt, buffer, MAXSTR );
|
|
varg_printf( g_debug, buffer );
|
|
}
|
|
|
|
if( Commands[cmd].fFlag & VARG_FLAG_NOFLAG ){
|
|
varg_printf( g_debug, _T("%1!s! "), Commands[cmd].strParam );
|
|
}else{
|
|
if( !(Commands[cmd].fFlag & (VARG_FLAG_VERB|VARG_FLAG_ADVERB)) ){
|
|
varg_printf( g_debug, _T("%1!c!"), g_strPrefix[0] );
|
|
}else if( !IsEmpty( g_strVerbPrefix ) ){
|
|
varg_printf( g_debug, _T("%1!c!"), g_strVerbPrefix[0] );
|
|
}
|
|
if( ArgExpected( &Commands[cmd] ) ){
|
|
varg_printf( g_debug, _T("%1!s!%2!s! %3!s! "),
|
|
Commands[cmd].fFlag&VARG_FLAG_NEGATE ? _T("[-]") : _T(""),
|
|
bUseArg1 ? Commands[cmd].strArg1 : Commands[cmd].strArg2,
|
|
Commands[cmd].strParam
|
|
);
|
|
}else{
|
|
varg_printf( g_debug, _T("%1!s!%2!s! "),
|
|
Commands[cmd].fFlag&VARG_FLAG_NEGATE ? _T("[-]") : _T(""),
|
|
bUseArg1 ? Commands[cmd].strArg1 : Commands[cmd].strArg2
|
|
);
|
|
}
|
|
}
|
|
|
|
if( bEOL ){
|
|
varg_printf( g_debug, _T("\n") );
|
|
}
|
|
|
|
}
|
|
|
|
HRESULT
|
|
ValidateCommands()
|
|
{
|
|
int i,j;
|
|
HRESULT hr = ERROR_SUCCESS;
|
|
BOOL bVerbs = FALSE;
|
|
BOOL nDefinedVerbs = 0;
|
|
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST;i++){
|
|
UCHAR cond1 = (UCHAR)((Commands[i].dwSet & VARG_CONDITION) >> 16);
|
|
if( cond1 ){
|
|
BOOL bFound = FALSE;
|
|
for(j=0; Commands[j].fType != VARG_TYPE_LAST;j++){
|
|
UCHAR cond2 = (UCHAR)((Commands[j].dwSet & VARG_CONDITION) >> 16);
|
|
if( (cond1 & cond2) && Commands[j].bDefined ){
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if( ! bFound ){
|
|
for(j=0; Commands[j].fType != VARG_TYPE_LAST;j++){
|
|
UCHAR cond2 = (UCHAR)((Commands[j].dwSet & VARG_CONDITION) >> 16);
|
|
if( (cond1 & cond2) && !(Commands[j].fFlag & VARG_FLAG_VERB)){
|
|
Commands[j].fFlag |= VARG_FLAG_REQUIRED;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if( Commands[i].bDefined && (Commands[i].fFlag & VARG_FLAG_REQ_ADV) ){
|
|
BOOL bFound = FALSE;
|
|
WORD wVerb1 = (WORD)( Commands[i].dwVerb & 0x0000FFFF );
|
|
for(j=0; Commands[j].fType != VARG_TYPE_LAST;j++){
|
|
WORD wVerb2 = (WORD)(Commands[j].dwVerb & 0x0000FFFF);
|
|
if( Commands[j].bDefined && (wVerb1 == wVerb2) && (Commands[j].fFlag & VARG_FLAG_ADVERB) ){
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if( ! bFound ){
|
|
for(j=0; Commands[j].fType != VARG_TYPE_LAST;j++){
|
|
WORD wVerb2 = (WORD)(Commands[j].dwVerb & 0x0000FFFF);
|
|
if( wVerb1 == wVerb2 && Commands[j].fFlag & VARG_FLAG_ADVERB ){
|
|
Commands[j].fFlag |= VARG_FLAG_REQUIRED;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if( Commands[i].bDefined && Commands[i].dwSet ){
|
|
UCHAR excl1 = (UCHAR)((Commands[i].dwSet & VARG_EXCLUSIVE));
|
|
UCHAR incl1 = (UCHAR)((Commands[i].dwSet & VARG_INCLUSIVE) >> 8);
|
|
UCHAR grp_ex1 = (UCHAR)(((Commands[i].dwSet & VARG_GROUPEXCL) >> 24) & 0x0F);
|
|
for(j=i+1; Commands[j].fType != VARG_TYPE_LAST;j++){
|
|
if( Commands[j].dwSet ){
|
|
UCHAR excl2 = (UCHAR)((Commands[j].dwSet & VARG_EXCLUSIVE));
|
|
UCHAR incl2 = (UCHAR)((Commands[j].dwSet & VARG_INCLUSIVE) >> 8);
|
|
UCHAR grp_in2 = (UCHAR)((((Commands[j].dwSet & VARG_GROUPEXCL) >> 24) & 0xF0) >> 4 );
|
|
if( excl1 && (excl1 & excl2) && Commands[j].bDefined ){
|
|
PrintParam( 0, i, FALSE );
|
|
PrintParam( IDS_MESSAGE_AND, j, FALSE );
|
|
PrintMessage( g_debug, IDS_MESSAGE_EXCLUSIVE );
|
|
hr = ERROR_BAD_ARGUMENTS;
|
|
}
|
|
if( incl1 && (incl1 & incl2) && !Commands[j].bDefined){
|
|
PrintParam( 0, i, FALSE );
|
|
PrintParam( IDS_MESSAGE_REQUIRES, j, FALSE );
|
|
varg_printf( g_debug, _T("\n") );
|
|
hr = ERROR_BAD_ARGUMENTS;
|
|
}
|
|
if( grp_ex1 && (grp_in2 & grp_ex1) && Commands[j].bDefined ){
|
|
PrintParam( 0, i, FALSE );
|
|
PrintParam( IDS_MESSAGE_AND, j, FALSE );
|
|
PrintMessage( g_debug, IDS_MESSAGE_EXCLUSIVE );
|
|
hr = ERROR_BAD_ARGUMENTS;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( Commands[i].bDefined && (Commands[i].fFlag & VARG_FLAG_LITERAL) ){
|
|
LPTSTR strValues;
|
|
LPTSTR strCheck;
|
|
LPTSTR strArg;
|
|
BOOL bFound = FALSE;
|
|
switch( Commands[i].fType ){
|
|
case VARG_TYPE_MSZ:
|
|
case VARG_TYPE_STR:
|
|
|
|
strArg = Commands[i].strValue;
|
|
while( strArg != NULL && !(Commands[i].fFlag & VARG_FLAG_BADSYNTAX) ){
|
|
strValues = varg_strdup( Commands[i].strParam );
|
|
if( NULL != strValues ){
|
|
strCheck = _tcstok( strValues, _T("<>[]|") );
|
|
while( !bFound && strCheck != NULL ){
|
|
if( _tcsicmp( strCheck, strArg ) == 0 ){
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
strCheck = _tcstok( NULL, _T("<>[]|") );
|
|
}
|
|
}
|
|
VARG_FREE( strValues );
|
|
if( !bFound ){
|
|
Commands[i].fFlag |= VARG_FLAG_BADSYNTAX;
|
|
hr = ERROR_BAD_ARGUMENTS;
|
|
}
|
|
if( Commands[i].fType == VARG_TYPE_MSZ ){
|
|
strArg += _tcslen( strArg ) + 1;
|
|
bFound = FALSE;
|
|
if( *strArg == _T('\0') ){
|
|
strArg = NULL;
|
|
}
|
|
}else{
|
|
strArg = NULL;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
hr = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
}
|
|
|
|
for(i=0; Commands[i].fType != VARG_TYPE_LAST;i++){
|
|
if( Commands[i].fFlag & VARG_FLAG_VERB ){
|
|
if( Commands[i].bDefined ){
|
|
nDefinedVerbs++;
|
|
}
|
|
bVerbs = TRUE;
|
|
}
|
|
if( (Commands[i].fFlag & VARG_FLAG_REQUIRED) && !Commands[i].bDefined){
|
|
PrintParam( IDS_MESSAGE_MISSING, i, TRUE );
|
|
hr = ERROR_BAD_ARGUMENTS;
|
|
}
|
|
if( Commands[i].fFlag & VARG_FLAG_BADSYNTAX ){
|
|
PrintParam( IDS_MESSAGE_BADSYNTAX, i, TRUE );
|
|
hr = ERROR_BAD_ARGUMENTS;
|
|
}
|
|
}
|
|
|
|
if( bVerbs && nDefinedVerbs == 0 ){
|
|
PrintMessage( g_debug, IDS_MESSAGE_NOVERB );
|
|
hr = ERROR_BAD_ARGUMENTS;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
Utility Functions
|
|
\*****************************************************************************/
|
|
|
|
HRESULT GetUserInput( LPTSTR strBuffer, ULONG lSize, BOOL bEcho )
|
|
{
|
|
TCHAR c = _T('\0');
|
|
UCHAR a;
|
|
ULONG i = 0;
|
|
BOOL bDone = FALSE;
|
|
HANDLE hInput = NULL;
|
|
DWORD dwSize;
|
|
DWORD dwMode;
|
|
|
|
hInput = GetStdHandle( STD_INPUT_HANDLE );
|
|
|
|
GetConsoleMode( hInput, &dwMode);
|
|
SetConsoleMode( hInput, (~(ENABLE_ECHO_INPUT|ENABLE_LINE_INPUT)) & dwMode);
|
|
|
|
while( !bDone ){
|
|
if( (GetFileType(hInput) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR ){
|
|
BOOL bRead = ReadFile( hInput, &a, 1, &dwSize, NULL );
|
|
if( 0 == dwSize || !bRead ){
|
|
c = _T('\n');
|
|
}else{
|
|
MultiByteToChar( a, c );
|
|
if( _T('\r') == c ){
|
|
bRead = ReadFile( hInput, &a, 1, &dwSize, NULL );
|
|
}
|
|
}
|
|
}else{
|
|
ReadConsole( hInput, &c, 1, &dwSize, NULL );
|
|
}
|
|
switch( c ){
|
|
case 8:
|
|
if( i > 0 ){
|
|
strBuffer[i--] = _T('\0');
|
|
if(bEcho){
|
|
_tprintf( _T("%c %c"), c, c );
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
FreeCmd();
|
|
SetConsoleMode(hInput, dwMode);
|
|
exit(0);
|
|
case _T('\r'):
|
|
case _T('\n'):
|
|
bDone = TRUE;
|
|
varg_printf( g_normal, _T("\n") );
|
|
break;
|
|
default:
|
|
if( i < (lSize-1) ){
|
|
strBuffer[i++] = (TCHAR)c;
|
|
if( bEcho ){
|
|
varg_printf( g_normal, _T("%1!c!"), c );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SetConsoleMode(hInput, dwMode);
|
|
|
|
if( i > lSize ){
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}else{
|
|
strBuffer[i] = _T('\0');
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
DWORD
|
|
CheckFile( LPTSTR strFile, DWORD dwFlags )
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
HANDLE hFile;
|
|
|
|
hFile = CreateFile(
|
|
strFile,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
if( hFile == INVALID_HANDLE_VALUE){
|
|
dwStatus = GetLastError();
|
|
}
|
|
CloseHandle(hFile);
|
|
|
|
if( dwFlags & VARG_CF_OVERWRITE ){
|
|
if( ERROR_FILE_NOT_FOUND == dwStatus ){
|
|
dwStatus = ERROR_SUCCESS;
|
|
}else if( ERROR_PATH_NOT_FOUND == dwStatus){
|
|
return dwStatus;
|
|
}else if( dwFlags & VARG_CF_PROMPT ){
|
|
|
|
TCHAR buffer[MAXSTR] = _T("");
|
|
TCHAR yes[16];
|
|
|
|
PrintMessage( g_normal, IDS_CF_OVERWRITE, strFile );
|
|
GetUserInput( buffer, MAXSTR, TRUE );
|
|
LoadString( NULL, IDS_ARG_YES, yes, 16 );
|
|
|
|
if( FindString( buffer, yes ) ){
|
|
dwStatus = ERROR_SUCCESS;
|
|
}else{
|
|
dwStatus = ERROR_ALREADY_EXISTS;
|
|
}
|
|
}
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
HRESULT
|
|
ExpandFiles( LPTSTR* mszFiles, BOOL bMultiple )
|
|
{
|
|
LPTSTR strFiles = NULL;
|
|
LPTSTR strExpand;
|
|
|
|
TCHAR buffer[_MAX_PATH];
|
|
TCHAR drive[_MAX_DRIVE];
|
|
TCHAR dir[_MAX_DIR];
|
|
TCHAR fname[_MAX_FNAME];
|
|
TCHAR ext[_MAX_EXT];
|
|
HANDLE hFile = NULL;
|
|
WIN32_FIND_DATA file;
|
|
|
|
strExpand = *mszFiles;
|
|
while( strExpand != NULL && *strExpand != _T('\0')){
|
|
_tsplitpath( strExpand, drive, dir, fname, ext );
|
|
hFile = FindFirstFile( strExpand, &file );
|
|
|
|
if( hFile != INVALID_HANDLE_VALUE){
|
|
do{
|
|
if( !( !_tcscmp(file.cFileName, _T(".") ) || !_tcscmp(file.cFileName, _T("..")) ) ){
|
|
_tmakepath( buffer, drive, dir, file.cFileName, _T("") );
|
|
AddStringToMsz( &strFiles, buffer );
|
|
}
|
|
}while( FindNextFile( hFile, &file ) == TRUE );
|
|
|
|
FindClose( hFile );
|
|
|
|
}else{
|
|
return GetLastError();
|
|
}
|
|
if( bMultiple ){
|
|
strExpand += _tcslen( strExpand )+1;
|
|
}else{
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if( NULL != strFiles ){
|
|
VARG_FREE( *mszFiles );
|
|
*mszFiles = strFiles;
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
BOOL FindString( LPTSTR strBuffer, LPTSTR strMatch )
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
|
|
LPTSTR buffer;
|
|
LPTSTR match;
|
|
|
|
buffer = varg_strdup( strBuffer );
|
|
match = varg_strdup( strMatch );
|
|
|
|
if( buffer != NULL && match != NULL ){
|
|
_tcslwr( buffer );
|
|
_tcslwr( match );
|
|
|
|
if( _tcsstr( buffer, match ) ){
|
|
bReturn = TRUE;
|
|
}
|
|
}
|
|
|
|
VARG_FREE( match );
|
|
VARG_FREE( buffer );
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
HRESULT
|
|
ParseTime( LPTSTR strTime, SYSTEMTIME* pstTime, BOOL bDate )
|
|
{
|
|
TCHAR buffer[MAXSTR];
|
|
TCHAR PM[9] = _T("pm");
|
|
TCHAR AM[9] = _T("am");
|
|
TCHAR strDateSep[8] = _T("/");
|
|
TCHAR strTimeSep[8] = _T(":");
|
|
ULONG l;
|
|
LPTSTR str, str2;
|
|
int nDateFormat = 0;
|
|
BOOL bValid = TRUE;
|
|
FILETIME ft;
|
|
HRESULT hr = ERROR_SUCCESS;
|
|
|
|
ZeroMemory( pstTime, sizeof( SYSTEMTIME ) );
|
|
|
|
if( GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_IDATE, buffer, MAXSTR ) > 1 ){
|
|
nDateFormat = _ttoi( buffer );
|
|
}
|
|
if( GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_S1159, buffer, 9 ) > 1 ){
|
|
hr = StringCchCopy( AM, 9, buffer );
|
|
}
|
|
if( GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_S2359, buffer, 9 ) > 1 ){
|
|
hr = StringCchCopy( PM, 9, buffer );
|
|
}
|
|
if( GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STIME, buffer, 8 ) > 1 ){
|
|
hr = StringCchCopy( strTimeSep, 8, buffer );
|
|
}
|
|
if( GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SDATE, buffer, 8 ) > 1 ){
|
|
hr = StringCchCopy( strDateSep, 8, buffer );
|
|
}
|
|
|
|
hr = StringCchCopy( buffer, MAXSTR, strTime );
|
|
|
|
str = _tcstok( buffer, _T(" \n\t") );
|
|
str2 = _tcstok( NULL, _T(" \n\t") );
|
|
while( str ){
|
|
if( _tcsstr( str, strDateSep ) ){
|
|
|
|
LPTSTR strMonth = NULL;
|
|
LPTSTR strDay = NULL;
|
|
LPTSTR strYear = NULL;
|
|
|
|
switch( nDateFormat ){
|
|
case 0:
|
|
strMonth = _tcstok( str, strDateSep );
|
|
strDay = _tcstok( NULL, strDateSep );
|
|
strYear = _tcstok( NULL, strDateSep );
|
|
break;
|
|
case 1:
|
|
strDay = _tcstok( str, strDateSep );
|
|
strMonth = _tcstok( NULL, strDateSep );
|
|
strYear = _tcstok( NULL, strDateSep );
|
|
break;
|
|
case 2:
|
|
strYear = _tcstok( str, strDateSep );
|
|
strMonth = _tcstok( NULL, strDateSep );
|
|
strDay = _tcstok( NULL, strDateSep );
|
|
break;
|
|
}
|
|
|
|
if( NULL != strMonth ){
|
|
hr = ReadLong( strMonth, &l, MAXWORD );
|
|
if( ERROR_SUCCESS == hr ){
|
|
pstTime->wMonth = (WORD)l;
|
|
}
|
|
}
|
|
if( NULL != strDay ){
|
|
hr = ReadLong( strDay, &l, MAXWORD );
|
|
if( ERROR_SUCCESS == hr ){
|
|
pstTime->wDay = (WORD)l;
|
|
}
|
|
}
|
|
if( NULL != strYear ){
|
|
hr = ReadLong( strYear, &l, MAXWORD );
|
|
if( ERROR_SUCCESS == hr ){
|
|
if( l < 100 ){
|
|
l += 2000;
|
|
}
|
|
pstTime->wYear = (WORD)l;
|
|
}
|
|
}
|
|
}else{
|
|
LPTSTR tok1 = NULL;
|
|
LPTSTR tok2 = NULL;
|
|
LPTSTR tok3 = NULL;
|
|
UINT nTok = 0;
|
|
BOOL bPM = FALSE;
|
|
BOOL bAM = FALSE;
|
|
LPTSTR szZero = _T("0");
|
|
|
|
bPM = FindString( str, PM );
|
|
bAM = FindString( str, AM );
|
|
|
|
tok1 = _tcstok( str, strTimeSep );
|
|
if( NULL != tok1 ){
|
|
nTok++;
|
|
tok2 = _tcstok( NULL, strTimeSep );
|
|
}else{
|
|
tok1 = szZero;
|
|
}
|
|
if( NULL != tok2 ){
|
|
nTok++;
|
|
tok3 = _tcstok( NULL, strTimeSep );
|
|
}else{
|
|
tok2 = szZero;
|
|
}
|
|
if( NULL != tok3 ){
|
|
nTok++;
|
|
}else{
|
|
tok3 = szZero;
|
|
}
|
|
if( bDate ){
|
|
nTok = 3;
|
|
}
|
|
switch( nTok ){
|
|
case 1:
|
|
hr = ReadLong( tok1, &l, MAXWORD );
|
|
if( ERROR_SUCCESS == hr ){
|
|
pstTime->wSecond = (WORD)l;
|
|
}
|
|
break;
|
|
case 2:
|
|
hr = ReadLong( tok1, &l, MAXWORD );
|
|
if( ERROR_SUCCESS == hr ){
|
|
pstTime->wMinute = (WORD)l;
|
|
hr = ReadLong( tok2, &l, MAXWORD );
|
|
if( ERROR_SUCCESS == hr ){
|
|
pstTime->wSecond = (WORD)l;
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
hr = ReadLong( tok1, &l, MAXWORD );
|
|
if( ERROR_SUCCESS == hr ){
|
|
pstTime->wHour = (WORD)l;
|
|
hr = ReadLong( tok2, &l, MAXWORD );
|
|
if( ERROR_SUCCESS == hr ){
|
|
pstTime->wMinute = (WORD)l;
|
|
hr = ReadLong( tok3, &l, MAXWORD );
|
|
if( ERROR_SUCCESS == hr ){
|
|
pstTime->wSecond = (WORD)l;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if( ERROR_SUCCESS == hr ){
|
|
if( bPM ){
|
|
if( pstTime->wHour < 12 ){
|
|
pstTime->wHour += 12;
|
|
}else if( pstTime->wHour > 12 ){
|
|
PrintMessage( g_debug, IDS_MESSAGE_BADTIME, PM );
|
|
}
|
|
}
|
|
if( bAM ){
|
|
if( pstTime->wHour > 12 ){
|
|
PrintMessage( g_debug, IDS_MESSAGE_BADTIME, AM );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
str = str2;
|
|
str2 = NULL;
|
|
}
|
|
|
|
if( bDate && ERROR_SUCCESS == hr ){
|
|
bValid = SystemTimeToFileTime( pstTime, &ft );
|
|
if( !bValid ){
|
|
hr = GetLastError();
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
void PrintError( HRESULT hr )
|
|
{
|
|
PrintErrorEx( hr, NULL );
|
|
}
|
|
|
|
void PrintErrorEx( HRESULT hr, LPTSTR strModule, ... )
|
|
{
|
|
LPVOID lpMsgBuf = NULL;
|
|
HINSTANCE hModule = NULL;
|
|
DWORD dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER;
|
|
|
|
va_list args;
|
|
va_start( args, strModule );
|
|
|
|
if(hr == 0){
|
|
hr = GetLastError();
|
|
}
|
|
|
|
if( strModule != NULL ){
|
|
hModule = LoadLibrary( strModule );
|
|
}
|
|
|
|
if ( NULL != hModule ) {
|
|
dwFlags |= FORMAT_MESSAGE_FROM_HMODULE;
|
|
}else{
|
|
dwFlags |= FORMAT_MESSAGE_FROM_SYSTEM;
|
|
}
|
|
|
|
__try{
|
|
|
|
FormatMessage(
|
|
dwFlags,
|
|
hModule,
|
|
hr,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
(LPTSTR)&lpMsgBuf,
|
|
MAXSTR,
|
|
&args
|
|
);
|
|
|
|
if( g_nDebug >= 0 ){
|
|
PrintMessage( g_debug, IDS_MESSAGE_ERROR_DBG, hr );
|
|
}else{
|
|
PrintMessage( g_debug, IDS_MESSAGE_ERROR );
|
|
}
|
|
if( NULL == lpMsgBuf ){
|
|
PrintMessage( g_debug, IDS_MESSAGE_UNKNOWN );
|
|
}else{
|
|
varg_printf( g_debug, _T("%1!s!\n"), (LPTSTR)lpMsgBuf );
|
|
}
|
|
|
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
PrintMessage( g_debug, IDS_MESSAGE_UNKNOWN );
|
|
}
|
|
|
|
if ( NULL != hModule ) {
|
|
FreeLibrary( hModule );
|
|
}
|
|
|
|
LocalFree( lpMsgBuf );
|
|
}
|
|
|
|
int
|
|
PrintDateEx( SHORT color, SYSTEMTIME* st )
|
|
{
|
|
HRESULT hr;
|
|
TCHAR buffer[MAXSTR];
|
|
TCHAR strDateSep[8] = _T("/");
|
|
TCHAR strTimeSep[8] = _T(":");
|
|
int nDateFormat = 0;
|
|
int nOut = 0;
|
|
|
|
if( GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_IDATE, buffer, MAXSTR ) > 0 ){
|
|
nDateFormat = _ttoi( buffer );
|
|
}
|
|
if( GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STIME, buffer, 8 ) > 0 ){
|
|
hr = StringCchCopy( strTimeSep, 8, buffer );
|
|
}
|
|
if( GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SDATE, buffer, 8 ) > 0 ){
|
|
hr = StringCchCopy( strDateSep, 8, buffer );
|
|
}
|
|
|
|
if( st->wMonth ){
|
|
switch( nDateFormat ){
|
|
case 0:
|
|
nOut = varg_printf( color, _T("%1!d!%2!s!%3!d!%4!s!%5!d! "),
|
|
st->wMonth,
|
|
strDateSep,
|
|
st->wDay,
|
|
strDateSep,
|
|
st->wYear
|
|
);
|
|
break;
|
|
case 1:
|
|
nOut = varg_printf( color, _T("%1!d!%2!s!%3!d!%4!s!%5!d! "),
|
|
st->wDay,
|
|
strDateSep,
|
|
st->wMonth,
|
|
strDateSep,
|
|
st->wYear
|
|
);
|
|
break;
|
|
case 2:
|
|
nOut = varg_printf( color, _T("%1!d!%2!s!%3!d!%4!s!%5!d! "),
|
|
st->wYear,
|
|
strDateSep,
|
|
st->wMonth,
|
|
strDateSep,
|
|
st->wDay
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
|
|
nOut += varg_printf( color, _T("%1!d!%2!s!%3!02d!%4!s!%5!02d!"),
|
|
st->wHour,
|
|
strTimeSep,
|
|
st->wMinute,
|
|
strTimeSep,
|
|
st->wSecond
|
|
);
|
|
|
|
return nOut;
|
|
}
|
|
|
|
void PrintDate( SYSTEMTIME* st )
|
|
{
|
|
PrintDateEx( g_normal, st );
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
VSetThreadUILanguage
|
|
|
|
This routine sets the thread UI language based on the console codepage.
|
|
|
|
9-29-00 WeiWu Created.
|
|
6-19-01 coreym Adapted from Base\Win32\Winnls so that it works in W2K
|
|
|
|
\*****************************************************************************/
|
|
|
|
LANGID WINAPI
|
|
VSetThreadUILanguage(WORD wReserved)
|
|
{
|
|
//
|
|
// Cache system locale and CP info
|
|
//
|
|
static LCID s_lidSystem = 0;
|
|
static UINT s_uiSysCp = 0;
|
|
static UINT s_uiSysOEMCp = 0;
|
|
|
|
ULONG uiUserUICp = 0;
|
|
ULONG uiUserUIOEMCp = 0;
|
|
TCHAR szData[16];
|
|
|
|
LANGID lidUserUI = GetUserDefaultUILanguage();
|
|
LCID lcidThreadOld = GetThreadLocale();
|
|
|
|
//
|
|
// Set default thread locale to EN-US
|
|
//
|
|
// This allow us to fall back to English UI to avoid trashed characters
|
|
// when console doesn't meet the criteria of rendering native UI.
|
|
//
|
|
LCID lcidThread = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
|
|
UINT uiConsoleCp = GetConsoleOutputCP();
|
|
|
|
UNREFERENCED_PARAMETER(wReserved);
|
|
|
|
//
|
|
// Get cached system locale and CP info.
|
|
//
|
|
if (!s_uiSysCp) {
|
|
LCID lcidSystem = GetSystemDefaultLCID();
|
|
|
|
if (lcidSystem) {
|
|
//
|
|
// Get ANSI CP
|
|
//
|
|
GetLocaleInfo(lcidSystem, LOCALE_IDEFAULTANSICODEPAGE, szData, sizeof(szData)/sizeof(TCHAR));
|
|
uiUserUICp = _ttol(szData);
|
|
|
|
//
|
|
// Get OEM CP
|
|
//
|
|
GetLocaleInfo(lcidSystem, LOCALE_IDEFAULTCODEPAGE, szData, sizeof(szData)/sizeof(TCHAR));
|
|
s_uiSysOEMCp = _ttol(szData);
|
|
|
|
//
|
|
// Cache system primary langauge
|
|
//
|
|
s_lidSystem = PRIMARYLANGID(LANGIDFROMLCID(lcidSystem));
|
|
}
|
|
}
|
|
|
|
//
|
|
// Don't cache user UI language and CP info, UI language can be changed without system reboot.
|
|
//
|
|
if (lidUserUI) {
|
|
GetLocaleInfo(MAKELCID(lidUserUI,SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, szData, sizeof(szData)/sizeof(TCHAR));
|
|
uiUserUICp = _ttol(szData);
|
|
|
|
GetLocaleInfo(MAKELCID(lidUserUI,SORT_DEFAULT), LOCALE_IDEFAULTCODEPAGE, szData, sizeof(szData)/sizeof(TCHAR));
|
|
uiUserUIOEMCp = _ttol(szData);
|
|
}
|
|
|
|
//
|
|
// Complex scripts cannot be rendered in the console, so we
|
|
// force the English (US) resource.
|
|
//
|
|
if (uiConsoleCp &&
|
|
s_lidSystem != LANG_ARABIC &&
|
|
s_lidSystem != LANG_HEBREW &&
|
|
s_lidSystem != LANG_VIETNAMESE &&
|
|
s_lidSystem != LANG_THAI) {
|
|
//
|
|
// Use UI language for console only when console CP, system CP and UI language CP match.
|
|
//
|
|
if ((uiConsoleCp == s_uiSysCp || uiConsoleCp == s_uiSysOEMCp) &&
|
|
(uiConsoleCp == uiUserUICp || uiConsoleCp == uiUserUIOEMCp)) {
|
|
|
|
lcidThread = MAKELCID(lidUserUI, SORT_DEFAULT);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the thread locale if it's different from the currently set
|
|
// thread locale.
|
|
//
|
|
if ((lcidThread != lcidThreadOld) && (!SetThreadLocale(lcidThread))) {
|
|
lcidThread = lcidThreadOld;
|
|
}
|
|
|
|
//
|
|
// Return the thread locale that was set.
|
|
//
|
|
return (LANGIDFROMLCID(lcidThread));
|
|
}
|