|
|
/**********************************************************************/ /** Microsoft Windows/NT **/ /** Copyright(c) Microsoft Corporation, 1997 - 1998 **/ /**********************************************************************/
/*
format.cpp FILE HISTORY: */
#include "stdafx.h"
#include "tfschar.h"
#include "mprapi.h"
#include "rtrstr.h"
#include "format.h"
#include "raserror.h"
#include "mprerror.h"
//----------------------------------------------------------------------------
// Function: FormatSystemError
//
// Formats an error code using '::FormatMessage', '::MprAdminGetErrorString',
// or '::RasAdminGetErrorString', or all the above (the default).
// If 'psFormat' is specified, it is used to format the error-string
// into 'sError'.
//----------------------------------------------------------------------------
DWORD FormatSystemError( IN HRESULT hrErr, LPTSTR pszBuffer, UINT cchBuffer, IN UINT idsFormat, IN DWORD dwFormatFlags ) { DWORD dwErr = WIN32_FROM_HRESULT(hrErr); DWORD dwRet = NO_ERROR; TCHAR* pszErr = NULL; WCHAR* pwsErr = NULL; CString sError;
dwFormatFlags &= FSEFLAG_ANYMESSAGE;
do {
//
// See if 'FSEFLAG_MPRMESSAGE' is specified
//
if (dwFormatFlags & FSEFLAG_MPRMESSAGE) { dwFormatFlags &= ~FSEFLAG_MPRMESSAGE;
if (((dwErr >= ROUTEBASE) && (dwErr <= ROUTEBASEEND)) || ((dwErr >= RASBASE) && (dwErr <= RASBASEEND))) { //
// Try retrieving a string from rasmsg.dll or mprmsg.dll
//
dwRet = ::MprAdminGetErrorString(dwErr, &pwsErr);
if (dwRet == NO_ERROR) { pszErr = StrDupTFromW(pwsErr); ::MprAdminBufferFree(pwsErr); break; } else if (!dwFormatFlags) break;
dwRet = NO_ERROR; } else if (!dwFormatFlags) return ERROR_INVALID_PARAMETER; }
//
// See if 'FSEFLAG_SYSMESSAGE' is specified
//
if (dwFormatFlags & FSEFLAG_SYSMESSAGE) { dwFormatFlags &= ~FSEFLAG_SYSMESSAGE;
//
// Try retrieving a string from the system
//
dwRet = ::FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER| FORMAT_MESSAGE_FROM_SYSTEM, NULL, hrErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&pwsErr, 1, NULL );
if (dwRet) { pszErr = StrDupTFromW(pwsErr); LocalFree(pwsErr); break; } else if (!dwFormatFlags) break;
dwRet = NO_ERROR; }
} while (FALSE);
//
// If no string was found, format the error as a number.
//
if (!pszErr) { TCHAR szErr[12];
wsprintf(szErr, TEXT("%d"), dwErr);
pszErr = StrDup(szErr); }
//
// Format the string into the caller's argument
//
if (idsFormat) AfxFormatString1(sError, idsFormat, pszErr); else sError = pszErr;
// Finally, copy the output
StrnCpy(pszBuffer, (LPCTSTR) sError, cchBuffer);
delete pszErr;
return dwRet; }
//
// Forward declaration of utility function used by 'FormatNumber'
//
TCHAR* padultoa( UINT val, TCHAR* pszBuf, INT width );
//----------------------------------------------------------------------------
// Function: FormatNumber
//
// This function takes an integer and formats a string with the value
// represented by the number, grouping digits by powers of one-thousand
//----------------------------------------------------------------------------
VOID FormatNumber(DWORD dwNumber, LPTSTR pszBuffer, UINT cchBuffer, BOOL fSigned) { Assert(cchBuffer > 14); static TCHAR szNegativeSign[4] = TEXT(""); static TCHAR szThousandsSeparator[4] = TEXT("");
DWORD i, dwLength; TCHAR szDigits[12] = {0}, pszTemp[20] = {0};
//
// Retrieve the thousands-separator for the user's locale
//
if (szThousandsSeparator[0] == TEXT('\0')) { ::GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szThousandsSeparator, 4 ); }
//
// If we are formatting a signed value, see if the value is negative
//
if (fSigned) { if ((INT)dwNumber >= 0) fSigned = FALSE; else { //
// The value is negative; retrieve the locale's negative-sign
//
if (szNegativeSign[0] == TEXT('\0')) {
::GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SNEGATIVESIGN, szNegativeSign, 4 ); }
dwNumber = abs((INT)dwNumber); } }
//
// Convert the number to a string without thousands-separators
//
padultoa(dwNumber, szDigits, 0);
dwLength = lstrlen(szDigits);
//
// If the length of the string without separators is n,
// then the length of the string with separators is n + (n - 1) / 3
//
i = dwLength; dwLength += (dwLength - 1) / 3;
//
// Write the number to the buffer in reverse
//
TCHAR* pszsrc, *pszdst;
pszsrc = szDigits + i - 1; pszdst = pszTemp + dwLength;
*pszdst-- = TEXT('\0');
while (TRUE) { if (i--) { *pszdst-- = *pszsrc--; } else { break; } if (i--) { *pszdst-- = *pszsrc--; } else { break; } if (i--) { *pszdst-- = *pszsrc--; } else { break; } if (i) { *pszdst-- = *szThousandsSeparator; } else { break; } }
pszBuffer[0] = 0; if (fSigned) lstrcat(pszBuffer, szNegativeSign);
lstrcat(pszBuffer, pszTemp); }
//----------------------------------------------------------------------------
// Function: padultoa
//
// This functions formats the specified unsigned integer
// into the specified string buffer, padding the buffer
// so that it is at least the specified width.
//
// It is assumed that the buffer is at least wide enough
// to contain the output, so this function does not truncate
// the conversion result to the length of the 'width' parameter.
//----------------------------------------------------------------------------
TCHAR* padultoa( UINT val, TCHAR* pszBuf, INT width ) {
TCHAR temp; PTSTR psz, zsp;
psz = pszBuf;
//
// write the digits in reverse order
//
do {
*psz++ = TEXT('0') + (val % 10); val /= 10;
} while(val > 0);
//
// pad the string to the required width
//
zsp = pszBuf + width; while (psz < zsp) { *psz++ = TEXT('0'); }
*psz-- = TEXT('\0');
//
// reverse the digits
//
for (zsp = pszBuf; zsp < psz; zsp++, psz--) {
temp = *psz; *psz = *zsp; *zsp = temp; }
//
// return the result
//
return pszBuf; }
//----------------------------------------------------------------------------
// Function: FormatListString
//
// Formats a list of strings as a single string, using the list-separator
// for the current-user's locale.
//----------------------------------------------------------------------------
VOID FormatListString( IN CStringList& strList, IN CString& sListString, IN LPCTSTR pszSeparator ) {
static TCHAR szListSeparator[4] = TEXT(""); POSITION pos;
sListString.Empty();
pos = strList.GetHeadPosition();
while (pos) {
//
// Add the next string
//
sListString += strList.GetNext(pos);
//
// If any strings are left, append the list-separator
//
if (pos) {
//
// Load the list-separator if necessary
//
if (!pszSeparator && szListSeparator[0] == TEXT('\0')) {
GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SLIST, szListSeparator, 4 );
lstrcat(szListSeparator, TEXT(" ")); }
//
// Append the list-separator
//
sListString += (pszSeparator ? pszSeparator : szListSeparator); } } }
//----------------------------------------------------------------------------
// Function: FormatHexBytes
//
// Formats an array of bytes as a string.
//----------------------------------------------------------------------------
VOID FormatHexBytes( IN BYTE* pBytes, IN DWORD dwCount, IN CString& sBytes, IN TCHAR chDelimiter ) {
TCHAR* psz;
sBytes.Empty();
if (!dwCount) { return; }
psz = sBytes.GetBufferSetLength(dwCount * 3 + 1);
for ( ; dwCount > 1; pBytes++, dwCount--) {
*psz++ = c_szHexCharacters[*pBytes / 16]; *psz++ = c_szHexCharacters[*pBytes % 16]; *psz++ = chDelimiter; }
*psz++ = c_szHexCharacters[*pBytes / 16]; *psz++ = c_szHexCharacters[*pBytes % 16]; *psz++ = TEXT('\0');
sBytes.ReleaseBuffer(); }
/*!--------------------------------------------------------------------------
DisplayErrorMessage - Author: KennT ---------------------------------------------------------------------------*/ void DisplayErrorMessage(HWND hWndParent, HRESULT hr) { if (FHrSucceeded(hr)) return;
TCHAR szErr[2048];
FormatSystemError(hr, szErr, DimensionOf(szErr), 0, FSEFLAG_SYSMESSAGE | FSEFLAG_MPRMESSAGE ); AfxMessageBox(szErr); // ::MessageBox(hWndParent, szErr, NULL, MB_OK);
}
/*!--------------------------------------------------------------------------
DisplayStringErrorMessage2 - Author: KennT ---------------------------------------------------------------------------*/ void DisplayStringErrorMessage2(HWND hWndParent, LPCTSTR pszTopLevelText, HRESULT hr) { if (FHrSucceeded(hr)) return;
TCHAR szText[4096]; TCHAR szErr[2048];
FormatSystemError(hr, szErr, DimensionOf(szErr), 0, FSEFLAG_SYSMESSAGE | FSEFLAG_MPRMESSAGE ); StrnCpy(szText, pszTopLevelText, DimensionOf(szText)); StrCat(szText, szErr); AfxMessageBox(szText); // ::MessageBox(hWndParent, szErr, NULL, MB_OK);
}
/*!--------------------------------------------------------------------------
DisplayIdErrorMessage2 - Author: KennT ---------------------------------------------------------------------------*/ void DisplayIdErrorMessage2(HWND hWndParent, UINT idsError, HRESULT hr) { if (FHrSucceeded(hr)) return;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString stError; TCHAR szErr[2048];
stError.LoadString(idsError); FormatSystemError(hr, szErr, DimensionOf(szErr), 0, FSEFLAG_SYSMESSAGE | FSEFLAG_MPRMESSAGE );
stError += szErr; AfxMessageBox(stError); // ::MessageBox(hWndParent, szErr, NULL, MB_OK);
}
//----------------------------------------------------------------------------
// Function: FormatDuration
//
// Formats a number as a duration, using the time-separator
// for the current-user's locale. dwBase is the number of units that make
// up a second (if dwBase==1 then the input is seconds, if dwBase==1000 then
// the input expected is in milliseconds.
//----------------------------------------------------------------------------
VOID FormatDuration( IN DWORD dwDuration, IN CString& sDuration, IN DWORD dwTimeBase, IN DWORD dwFormatFlags ) {
static TCHAR szTimeSeparator[4] = TEXT(""); TCHAR *psz, szOutput[64];
sDuration.Empty();
if ((dwFormatFlags & FDFLAG_ALL) == 0) { return; }
//
// Retrieve the time-separator if necessary
//
if (szTimeSeparator[0] == TEXT('\0')) {
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIME, szTimeSeparator, 4); }
//
// Concatenate the strings for the duration-components together
//
psz = szOutput; szOutput[0] = TEXT('\0'); dwFormatFlags &= FDFLAG_ALL;
if (dwFormatFlags & FDFLAG_DAYS) {
//
// Format the number of days if requested
//
padultoa(dwDuration / (24 * 60 * 60 * dwTimeBase), psz, 0); dwDuration %= (24 * 60 * 60 * dwTimeBase);
//
// Append the time-separator
//
if (dwFormatFlags &= ~FDFLAG_DAYS) { lstrcat(psz, szTimeSeparator); }
psz += lstrlen(psz); }
if (dwFormatFlags & FDFLAG_HOURS) {
//
// Format the number of hours if requested
//
padultoa(dwDuration / (60 * 60 * dwTimeBase), psz, 2); dwDuration %= (60 * 60 * dwTimeBase);
//
// Append the time-separator
//
if (dwFormatFlags &= ~FDFLAG_HOURS) { lstrcat(psz, szTimeSeparator); }
psz += lstrlen(psz); }
if (dwFormatFlags & FDFLAG_MINUTES) {
//
// Format the number of minutes
//
padultoa(dwDuration / (60 * dwTimeBase), psz, 2); dwDuration %= (60 * dwTimeBase);
//
// Append the time separator
//
if (dwFormatFlags &= ~FDFLAG_MINUTES) { lstrcat(psz, szTimeSeparator); }
psz += lstrlen(psz); }
if (dwFormatFlags & FDFLAG_SECONDS) {
//
// Format the number of seconds
//
padultoa(dwDuration / dwTimeBase, psz, 2); dwDuration %= dwTimeBase;
//
// Append the time-separator
//
if (dwFormatFlags &= ~FDFLAG_SECONDS) { lstrcat(psz, szTimeSeparator); }
psz += lstrlen(psz); }
if (dwFormatFlags & FDFLAG_MSECONDS) {
//
// Format the number of milliseconds
//
padultoa(dwDuration % dwTimeBase, psz, 0); psz += lstrlen(psz); }
sDuration = szOutput; }
/*---------------------------------------------------------------------------
IfIndexToNameMapping implementation ---------------------------------------------------------------------------*/
IfIndexToNameMapping::IfIndexToNameMapping() { }
IfIndexToNameMapping::~IfIndexToNameMapping() { // Iterate through the map and delete all the pointers
POSITION pos; LPVOID pvKey, pvValue;
for (pos = m_map.GetStartPosition(); pos; ) { m_map.GetNextAssoc(pos, pvKey, pvValue); delete (CString *) pvValue; pvValue = NULL; m_map.SetAt(pvKey, pvValue); } m_map.RemoveAll(); }
/*!--------------------------------------------------------------------------
IfIndexToNameMapping::Add - Author: KennT ---------------------------------------------------------------------------*/ HRESULT IfIndexToNameMapping::Add(ULONG ulIndex, LPCTSTR pszName) { HRESULT hr = hrOK; LPVOID pvKey, pvValue;
COM_PROTECT_TRY { pvKey = (LPVOID) ULongToPtr( ulIndex ); pvValue = NULL; // If we can find the value, don't add it
if (m_map.Lookup(pvKey, pvValue) == 0) { pvValue = (LPVOID) new CString(pszName); m_map.SetAt(pvKey, pvValue); } Assert(((CString *) pvValue)->CompareNoCase(pszName) == 0); } COM_PROTECT_CATCH; return hr; }
/*!--------------------------------------------------------------------------
IfIndexToNameMapping::Find - Author: KennT ---------------------------------------------------------------------------*/ LPCTSTR IfIndexToNameMapping::Find(ULONG ulIndex) { LPVOID pvValue = NULL; if (m_map.Lookup((LPVOID) ULongToPtr(ulIndex), pvValue)) return (LPCTSTR) *((CString *)pvValue); else return NULL; }
|