|
|
#include "convlog.h"
#include <logconst.h>
#define MAX_MONTH_SIZE 16
char szJan[MAX_MONTH_SIZE]; char szFeb[MAX_MONTH_SIZE]; char szMar[MAX_MONTH_SIZE]; char szApr[MAX_MONTH_SIZE]; char szMay[MAX_MONTH_SIZE]; char szJun[MAX_MONTH_SIZE]; char szJul[MAX_MONTH_SIZE]; char szAug[MAX_MONTH_SIZE]; char szSep[MAX_MONTH_SIZE]; char szOct[MAX_MONTH_SIZE]; char szNov[MAX_MONTH_SIZE]; char szDec[MAX_MONTH_SIZE];
//
// extended logging
//
DWORD dwHostNamePos = 0; DWORD dwUserNamePos = 0; DWORD dwDatePos = 0; DWORD dwTimePos = 0; DWORD dwMethodPos = 0; DWORD dwURIStemPos = 0; DWORD dwURIQueryPos = 0; DWORD dwHTTPStatusPos = 0; DWORD dwBytesSentPos = 0; DWORD dwBytesRecvPos = 0; DWORD dwServicePos = 0; DWORD dwVersionPos = 0; CHAR szGlobalDate[32] = {0}; CHAR szGlobalTime[32] = {0}; BOOL ExtendedFieldsDefined = FALSE;
BOOL InitDateStrings( VOID ) { HINSTANCE hInst = GetModuleHandle(NULL);
if ( hInst == NULL ) { return(FALSE); }
LoadString(hInst, IDS_JAN, szJan, sizeof(szJan)); LoadString(hInst, IDS_FEB, szFeb, sizeof(szFeb)); LoadString(hInst, IDS_MAR, szMar, sizeof(szMar)); LoadString(hInst, IDS_APR, szApr, sizeof(szApr)); LoadString(hInst, IDS_MAY, szMay, sizeof(szMay)); LoadString(hInst, IDS_JUN, szJun, sizeof(szJun)); LoadString(hInst, IDS_JUL, szJul, sizeof(szJul)); LoadString(hInst, IDS_AUG, szAug, sizeof(szAug)); LoadString(hInst, IDS_SEP, szSep, sizeof(szSep)); LoadString(hInst, IDS_OCT, szOct, sizeof(szOct)); LoadString(hInst, IDS_NOV, szNov, sizeof(szNov)); LoadString(hInst, IDS_DEC, szDec, sizeof(szDec));
return(TRUE); }
PCHAR FindChar( IN PCHAR cp, IN CHAR cTarget )
/*++
This procedure increments a character pointer until it finds a comma or the NULL character. if it finds a comma, it replaces it with a NULL and increments the pointer. if it finds a NULL, it merely returns without changing the character. --*/ { while ((*cp != cTarget) && (*cp != '\0')) cp++;
if (*cp == cTarget) { *cp = '\0'; cp++; cp = SkipWhite(cp); } return (cp); }
PCHAR FindMSINETLogDelimChar( IN PCHAR cp )
/*++
This procedure increments a character pointer until it finds a comma+space or the NULL character. if it finds a comma+space, it replaces the comma with a NULL and increments the pointer past the space. if it finds a NULL, it merely returns without changing the character. --*/ { while ( !(*cp == ',' && ISWHITE ( *(cp+1) )) && (*cp != '\0') && (*cp != '\r') && (*cp != '\n')) { cp++; } if (*cp == ',') { *cp = '\0'; cp++; cp = SkipWhite(cp); } else if ((*cp=='\r') || (*cp=='\n'))\ { *cp = '\0'; } return (cp); }
char * SkipWhite (char *cp) {
while (ISWHITE (*cp)) { cp++; } return (cp); }
#if 0
PCHAR ConvertDate( IN LPTSTR pszDate )
/*++
Convert the date from "15/May/1995" to "5/15/95" format --*/ { static char pszRetDate[100]; char *cpCurrent = pszDate;
int nMonth=1; int nDay=1; int nYear=90;
nDay = atoi( cpCurrent ); cpCurrent=FindChar(cpCurrent,'/'); if ( strncmp(cpCurrent,szJan,3) == 0 ) { nMonth = 1; } else if ( strncmp(cpCurrent,szFeb,3) == 0 ) { nMonth = 2; } else if ( strncmp(cpCurrent,szMar,3) == 0 ) { nMonth = 3; } else if ( strncmp(cpCurrent,szApr,3) == 0 ) { nMonth = 4; } else if ( strncmp(cpCurrent,szMay,3) == 0 ) { nMonth = 5; } else if ( strncmp(cpCurrent,szJun,3) == 0 ) { nMonth = 6; } else if ( strncmp(cpCurrent,szJul,3) == 0 ) { nMonth = 7; } else if ( strncmp(cpCurrent,szAug,3) == 0 ) { nMonth = 8; } else if ( strncmp(cpCurrent,szSep,3) == 0 ) { nMonth = 9; } else if ( strncmp(cpCurrent,szOct,3) == 0 ) { nMonth = 10; } else if ( strncmp(cpCurrent,szNov,3) == 0 ) { nMonth = 11; } else if ( strncmp(cpCurrent,szDec,3) == 0 ) { nMonth = 12; } cpCurrent=FindChar(cpCurrent,'/'); nYear = atoi( cpCurrent )%100; sprintf(pszRetDate,"%d/%d/%d",nMonth,nDay,nYear); return pszRetDate; } #endif
/* #pragma INTRINSA suppress=all */ DWORD GetLogLine ( IN FILE *fpInFile, IN PCHAR szBuf, IN DWORD cbBuf, IN LPINLOGLINE lpLogLine ) { BOOL bRetCode = GETLOG_ERROR; CHAR *cpCurrent; CHAR buf[8*1024];
static char szNULL[]=""; static char szEmpty[]="-"; static char szUnknownIP[] = "<UnknownIP>"; static char szW3Svc[] = "W3Svc"; static char szDefaultHTTPVersion[]="HTTP/1.0";
lpLogLine->szClientIP = szNULL; lpLogLine->szUserName = szNULL; lpLogLine->szDate = szNULL; lpLogLine->szTime = szNULL; lpLogLine->szService = szNULL; lpLogLine->szServerName = szNULL; lpLogLine->szServerIP = szNULL; lpLogLine->szProcTime = szNULL; lpLogLine->szBytesRec = szNULL; lpLogLine->szBytesSent = szNULL; lpLogLine->szServiceStatus = szNULL; lpLogLine->szWin32Status = szNULL; lpLogLine->szOperation = szNULL; lpLogLine->szTargetURL = szNULL; lpLogLine->szUserAgent = szNULL; lpLogLine->szReferer = szNULL; lpLogLine->szParameters = szNULL; lpLogLine->szVersion = szDefaultHTTPVersion;
if (NULL != fgets(szBuf, cbBuf, fpInFile)) {
szBuf = SkipWhite(szBuf); if ((szBuf[0] != '\n') && ( szBuf[0] != '\0')) //is this an empty line?
{ bRetCode = GETLOG_SUCCESS;
//
// set current char pointer to start of string
//
cpCurrent = szBuf;
if ( LogFileFormat == LOGFILE_NCSA ) { lpLogLine->szClientIP = szBuf;
cpCurrent = FindChar(cpCurrent, ' '); lpLogLine->szClientIP = GetMachineName(lpLogLine->szClientIP);
sprintf( buf,"%s %s",lpLogLine->szClientIP,cpCurrent); strcpy( szBuf, buf);
//
// After the strcpy the pointers cpCurrent and lpLogLine->szClientIP have
// the potential to be miss alligned if the dns name is shorter or longer than the IP
// address that it replaced. Simple fix reset the pointers to the beginning of the
// string.
//
lpLogLine->szClientIP = szBuf; cpCurrent = szBuf; while ((*cpCurrent != '\0') && (*cpCurrent != '[') ) { cpCurrent++; }
if ( *cpCurrent == '\0' ) { return(GETLOG_ERROR_PARSE_NCSA); }
} else if (LogFileFormat == LOGFILE_MSINET ) {
lpLogLine->szClientIP = szBuf; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
if (DoDNSConversion) { lpLogLine->szClientIP = GetMachineName( lpLogLine->szClientIP );
if ( NoFormatConversion ) { sprintf( buf,"%s, %s",lpLogLine->szClientIP,cpCurrent); strcpy( szBuf, buf); return(GETLOG_SUCCESS); } }
lpLogLine->szUserName = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szDate = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szTime = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szService = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szServerName = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szServerIP = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szProcTime = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szBytesRec = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szBytesSent = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szServiceStatus = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szWin32Status = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szOperation = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szTargetURL = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
lpLogLine->szParameters = cpCurrent; cpCurrent = FindMSINETLogDelimChar (cpCurrent);
if (lpLogLine->szClientIP[0] != '\0' && lpLogLine->szUserName[0] != '\0' && lpLogLine->szDate[0] != '\0' && lpLogLine->szTime[0] != '\0' && lpLogLine->szService[0] != '\0' && lpLogLine->szServerName[0] != '\0' && lpLogLine->szServerIP[0] != '\0' && lpLogLine->szProcTime[0] != '\0' && lpLogLine->szBytesRec[0] != '\0' && lpLogLine->szBytesSent[0] != '\0' && lpLogLine->szServiceStatus[0] != '\0' && lpLogLine->szWin32Status[0] != '\0' && lpLogLine->szOperation[0] != '\0' && lpLogLine->szTargetURL[0] != '\0' && lpLogLine->szParameters[0] != '\0' ) {
bRetCode = GETLOG_SUCCESS; } else { return(GETLOG_ERROR_PARSE_MSINET); }
} else if ( LogFileFormat == LOGFILE_CUSTOM ) {
//
// W3C Extended Logging
//
if ( szBuf[0] == '#' ) {
PCHAR pszFields; cpCurrent = FindChar(cpCurrent, '#'); bRetCode = GETLOG_SUCCESS;
if ( strncmp(cpCurrent, "Fields:", 7) == 0 ) {
DWORD pos;
//
// init positions
//
ExtendedFieldsDefined = TRUE; dwHostNamePos = 0; dwUserNamePos = 0; dwDatePos = 0; dwTimePos = 0; dwMethodPos = 0; dwURIStemPos = 0; dwURIQueryPos = 0; dwHTTPStatusPos = 0; dwBytesSentPos = 0; dwBytesRecvPos = 0; dwServicePos = 0; dwVersionPos = 0;
cpCurrent = FindChar(cpCurrent, ':'); (VOID)FindChar( cpCurrent, '\n' );
for (pos = 1; *cpCurrent != '\0'; pos++) {
PCHAR pszField = cpCurrent; cpCurrent=FindChar(cpCurrent,' ');
if ( _stricmp( pszField, EXTLOG_CLIENT_IP_ID ) == 0 ) { dwHostNamePos = pos; } else if ( _stricmp( pszField, EXTLOG_USERNAME_ID ) == 0 ) { dwUserNamePos = pos; } else if ( _stricmp( pszField, EXTLOG_DATE_ID ) == 0 ) { dwDatePos = pos; } else if ( _stricmp( pszField, EXTLOG_TIME_ID ) == 0 ) { dwTimePos = pos; } else if ( _stricmp( pszField, EXTLOG_METHOD_ID ) == 0 ) { dwMethodPos = pos; } else if ( _stricmp( pszField, EXTLOG_URI_STEM_ID ) == 0 ) { dwURIStemPos = pos; } else if ( _stricmp( pszField, EXTLOG_URI_QUERY_ID ) == 0 ) { dwURIQueryPos = pos; } else if ( _stricmp( pszField, EXTLOG_HTTP_STATUS_ID ) == 0 ) { dwHTTPStatusPos = pos; } else if ( _stricmp( pszField, EXTLOG_BYTES_SENT_ID ) == 0 ) { dwBytesSentPos = pos; } else if ( _stricmp( pszField, EXTLOG_BYTES_RECV_ID ) == 0 ) { dwBytesRecvPos = pos; } else if ( _stricmp( pszField, EXTLOG_SITE_NAME_ID ) == 0 ) { dwServicePos = pos; } else if ( _stricmp( pszField, EXTLOG_PROTOCOL_VERSION_ID ) == 0 ) { dwVersionPos = pos; } } }
if ( strncmp(cpCurrent, "Date:", 5) == 0 ) {
//
// Grab the global date
//
cpCurrent = FindChar(cpCurrent, ':');
CopyMemory(szGlobalDate,cpCurrent, sizeof("2000-01-01") - 1); szGlobalDate[10] = '\0';
//
// And the global time
//
cpCurrent = FindChar(cpCurrent, ' ');
CopyMemory(szGlobalTime,cpCurrent, sizeof("00:00:00") - 1); szGlobalTime[8] = '\0'; }
} else {
DWORD pos; PCHAR pszValue;
if ( !ExtendedFieldsDefined ) { return(GETLOG_ERROR_PARSE_EXTENDED); }
//
// Need at least 1 valid entry in the log line other than date & time
if ( (dwHostNamePos == 0) && (dwUserNamePos == 0) && (dwMethodPos == 0) && (dwURIStemPos == 0) && (dwURIQueryPos == 0) && (dwHTTPStatusPos == 0) && (dwBytesSentPos == 0) && (dwBytesRecvPos == 0) && (dwServicePos == 0) && (dwVersionPos == 0) ) { return GETLOG_ERROR; }
//
// loop through entries
//
lpLogLine->szClientIP = szEmpty; lpLogLine->szUserName = szEmpty; lpLogLine->szDate = szEmpty; lpLogLine->szTime = szEmpty; lpLogLine->szOperation = szEmpty; lpLogLine->szTargetURL = szEmpty; lpLogLine->szParameters = szEmpty; lpLogLine->szServiceStatus = szEmpty; lpLogLine->szBytesSent = szEmpty; lpLogLine->szBytesRec = szEmpty; lpLogLine->szService = szW3Svc; lpLogLine->szVersion = szDefaultHTTPVersion;
(VOID)FindChar( cpCurrent, '\n' ); for (pos = 1; *cpCurrent != '\0'; pos++) {
pszValue = cpCurrent; cpCurrent = FindChar(cpCurrent,' ');
if ( pos == dwHostNamePos ) { lpLogLine->szClientIP = pszValue; if (DoDNSConversion) { lpLogLine->szClientIP = GetMachineName( lpLogLine->szClientIP ); } } else if (pos == dwUserNamePos) {
lpLogLine->szUserName = pszValue; } else if (pos == dwDatePos) {
lpLogLine->szDate = pszValue; } else if (pos == dwTimePos) {
lpLogLine->szTime = pszValue; } else if (pos == dwMethodPos) {
lpLogLine->szOperation = pszValue; } else if (pos == dwURIStemPos) {
lpLogLine->szTargetURL = pszValue; } else if (pos == dwURIQueryPos) {
lpLogLine->szParameters = pszValue; } else if (pos == dwHTTPStatusPos) {
lpLogLine->szServiceStatus = pszValue; } else if (pos == dwBytesSentPos) {
lpLogLine->szBytesSent = pszValue; } else if (pos == dwBytesRecvPos) {
lpLogLine->szBytesRec = pszValue; } else if (pos == dwServicePos) {
lpLogLine->szService = pszValue; } else if (pos == dwVersionPos) {
lpLogLine->szVersion = pszValue; } }
if ( lpLogLine->szDate == szEmpty ) { lpLogLine->szDate = szGlobalDate; }
if ( lpLogLine->szTime == szEmpty ) { lpLogLine->szTime = szGlobalTime; }
bRetCode = GETLOG_SUCCESS; } } } // end if first char = NewLine
} // end if fgets != NULL
return (bRetCode); }
WORD DateStringToDOSDate( IN PCHAR szDate ) { char *szDay; char *szMonth; char *szYear; char *cpCurrent; char szTmpStr[20]; int iYear;
if ( LogFileFormat == LOGFILE_CUSTOM ) {
strcpy (szTmpStr, szDate); cpCurrent = szTmpStr;
szYear = cpCurrent; cpCurrent = FindChar(cpCurrent,'-');
szMonth = cpCurrent; cpCurrent = FindChar(cpCurrent,'-');
szDay = cpCurrent;
iYear=atoi(szYear); if ( iYear > 1980 ) { iYear -= 1980; }
} else {
strcpy (szTmpStr, szDate); cpCurrent = szTmpStr;
if ( dwDateFormat == DateFormatJapan ) { // YY/MM/DD
szYear = cpCurrent; cpCurrent = FindChar (cpCurrent, '/');
szMonth = cpCurrent; cpCurrent = FindChar (cpCurrent, '/');
szDay = cpCurrent; } else if (dwDateFormat == DateFormatGermany ) {
// DD.MM.YY
szDay = cpCurrent; cpCurrent = FindChar (cpCurrent, '.');
szMonth = cpCurrent; cpCurrent = FindChar (cpCurrent, '.');
szYear = cpCurrent;
} else { // MM/DD/YY
szMonth = cpCurrent; cpCurrent = FindChar (cpCurrent, '/');
szDay = cpCurrent; cpCurrent = FindChar (cpCurrent, '/');
szYear = cpCurrent; }
iYear=atoi(szYear);
if ( iYear < 80 ) { iYear += 2000; }
if (iYear > 1980 ) { iYear = iYear - 1980; } else if (iYear >= 80 ) { iYear = iYear - 80; } }
return ((iYear << 9) | (atoi(szMonth) << 5) | atoi(szDay));
} // DateStringToDOSDate
WORD TimeStringToDOSTime( IN PCHAR szTime, IN LPWORD lpwSec ) { char *cpCurrent; char *szHour; char *szMinute; char *szSecond; char szTmpStr[20];
strcpy (szTmpStr, szTime); cpCurrent = szTmpStr;
szHour = cpCurrent; cpCurrent = FindChar (cpCurrent, ':');
szMinute = cpCurrent; cpCurrent = FindChar (cpCurrent, ':');
szSecond = cpCurrent; *lpwSec = (WORD)atoi(szSecond);
return ( (atoi(szHour) << 11) | (atoi(szMinute) << 5) | (atoi(szSecond) / 2)); }
char * AscMonth ( IN WORD wMonth, IN char *szMonth ) { switch (wMonth) { case 1: strncpy (szMonth, szJan, 3); break; case 2: strncpy (szMonth, szFeb, 3); break; case 3: strncpy (szMonth, szMar, 3); break; case 4: strncpy (szMonth, szApr, 3); break; case 5: strncpy (szMonth, szMay, 3); break; case 6: strncpy (szMonth, szJun, 3); break; case 7: strncpy (szMonth, szJul, 3); break; case 8: strncpy (szMonth, szAug, 3); break; case 9: strncpy (szMonth, szSep, 3); break; case 10: strncpy (szMonth, szOct, 3); break; case 11: strncpy (szMonth, szNov, 3); break; case 12: strncpy (szMonth, szDec, 3); break; } //end switch
szMonth[3] = '\0'; return (szMonth); } //end AscMonth
FILE * StartNewOutputLog ( IN LPOUTFILESTATUS pOutFile, IN LPCSTR pszInFileName, IN PCHAR szDate ) { BOOL bRet; DWORD dwErr;
if (pOutFile->fpOutFile != NULL ) {
fclose(pOutFile->fpOutFile); pOutFile->fpOutFile = NULL;
bRet = MoveFileEx( pOutFile->szTmpFileName, pOutFile->szOutFileName, MOVEFILE_COPY_ALLOWED);
if (!bRet) {
dwErr = GetLastError(); switch (dwErr) { case ERROR_FILE_EXISTS: case ERROR_ALREADY_EXISTS: CombineFiles( pOutFile->szTmpFileName, pOutFile->szOutFileName); break; case ERROR_PATH_NOT_FOUND: break; default: printfids(IDS_FILE_ERR, dwErr); exit (1); break; } } printfids(IDS_FILE_CLOSE, pOutFile->szOutFileName); }
dwErr = GetTempPath(MAX_PATH, TempDir);
if (0 != dwErr) { GetTempFileName(TempDir, "mhi", 0, pOutFile->szTmpFileName); } else { GetTempFileName(".", "mhi", 0, pOutFile->szTmpFileName); }
pOutFile->fpOutFile = fopen(pOutFile->szTmpFileName, "w");
sprintf(pOutFile->szOutFileName, "%s%s%s", OutputDir, pszInFileName, DoDNSConversion? ".ncsa.dns" : ".ncsa" );
printfids (IDS_FILE_WRITE, pOutFile->szOutFileName);
return (pOutFile->fpOutFile);
} // StartNewOutputLog
FILE * StartNewOutputDumpLog ( IN LPOUTFILESTATUS pOutFile, IN LPCSTR pszInputFileName, IN LPCSTR pszExt ) { BOOL bRet; DWORD dwErr;
dwErr = GetTempPath(MAX_PATH, TempDir);
if (0 != dwErr) { GetTempFileName(TempDir, "mhi", 0, pOutFile->szTmpFileName); } else { GetTempFileName(".", "mhi", 0, pOutFile->szTmpFileName); }
pOutFile->fpOutFile = fopen(pOutFile->szTmpFileName, "w");
sprintf(pOutFile->szOutFileName,"%s%s%s", OutputDir, pszInputFileName, pszExt );
printfids (IDS_FILE_WRITE, pOutFile->szOutFileName); return (pOutFile->fpOutFile);
} // StartNewOutputDumpLog
/* #pragma INTRINSA suppress=all */ VOID CombineFiles( IN LPTSTR lpszNew, IN LPTSTR lpszExisting ) { FILE *fpExisting; FILE *fpNew; char szLine[4096];
printfids(IDS_FILE_EXIST, lpszExisting); fpNew = fopen(lpszNew, "r"); fpExisting = fopen(lpszExisting, "a");
fgets(szLine, sizeof(szLine), fpNew); // last line contains only EOF, but does not overwrite szLine.
// It should not be written.
while (!feof(fpNew)) { fputs(szLine, fpExisting); fgets(szLine, sizeof(szLine), fpNew); }
if (fpNew) { fclose(fpNew); }
if (fpExisting) { fclose(fpExisting); }
DeleteFile(lpszNew); }
void Usage( IN PCHAR szProg ) { CHAR szTemp[MAX_PATH];
GetTempPath(MAX_PATH, szTemp);
printfids(IDS_HEADER1); printfids(IDS_HEADER2); printfids(IDS_HEADER3); printfids(IDS_HEADER4);
printfids(IDS_USAGE1, szProg); printfids(IDS_USAGE2); printfids(IDS_USAGE3); printfids(IDS_USAGE4); printfids(IDS_USAGE5); printfids(IDS_USAGE7); printfids(IDS_USAGE8); printfids(IDS_USAGE9); printfids(IDS_USAGE10); printfids(IDS_USAGE11); printfids(IDS_USAGE12); printfids(IDS_USAGE13); printfids(IDS_USAGE14); printfids(IDS_USAGE15); printfids(IDS_USAGE16);
printfids(IDS_SAMPLE0, szProg); printfids(IDS_SAMPLE1, szProg); printfids(IDS_SAMPLE2, szProg); printfids(IDS_SAMPLE3, szProg); return; }
VOID printfids( IN DWORD ids, ... ) { CHAR szBuff[2048]; CHAR szString[2048]; WCHAR szOutput[2048]; va_list argList;
//
// Try and load the string
//
if ( !LoadString( GetModuleHandle( NULL ), ids, szString, sizeof( szString ) )) { printf( "Error loading string ID %d\n", ids );
return; }
va_start( argList, ids ); vsprintf( szBuff, szString, argList ); va_end( argList );
MultiByteToWideChar( CP_ACP, 0, szBuff, -1, szOutput, sizeof(szOutput)/sizeof(WCHAR)); WideCharToMultiByte( GetConsoleOutputCP(), 0, szOutput, wcslen(szOutput)+1, szBuff, sizeof(szBuff), NULL, NULL);
printf(szBuff ); }
|