Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

887 lines
23 KiB

/////////////////////////////////////////////////////////////////////////////
// UTIL.CPP
#include "common.h"
const char szNull[] = "\0"; // Also stNull, stzNull and wszNull for UNICODE
DWORD gGI_dwFlagsAutoReset = GI_dwDefaultFlags;
DWORD gGI_dwFlags = GI_dwDefaultFlags; // FAsciiSzToDWord() parsing flags
TCHAR * gGI_pchLast = NULL; // Pointer to the last character parsed
const char g_rgchHex[16*2+1] = "00112233445566778899aAbBcCdDeEfF";
// REVIEW: Get rid of MsgBox(TCHAR) for retail build
/////////////////////////////////////////////////////////////////////////////
int MsgBox(const TCHAR szText[], const TCHAR szTitle[], UINT uFlags)
{
return MessageBox(GetActiveWindow(), szText, szTitle, uFlags);
} // MsgBox
/////////////////////////////////////////////////////////////////////////////
int MsgBox(UINT wIdString, const TCHAR szTitle[], UINT uFlags)
{
TCHAR szT[1024];
(void)CchLoadString(wIdString, szT, LENGTH(szT));
return MessageBox(GetActiveWindow(), szT, szTitle, uFlags);
} // MsgBox
/////////////////////////////////////////////////////////////////////////////
int MsgBoxPrintf(const TCHAR szText[], const TCHAR szTitle[], UINT uFlags, ...)
{
TCHAR szT[1024];
va_list arglist;
va_start(arglist, uFlags);
wvsprintf(szT, szText, arglist);
Assert((int)lstrlen(szT) < LENGTH(szT));
return MessageBox(GetActiveWindow(), szT, szTitle, uFlags);
} // MsgBoxPrintf
/////////////////////////////////////////////////////////////////////////////
int MsgBoxPrintf(UINT wIdString, const TCHAR szTitle[], UINT uFlags, ...)
{
TCHAR szFmt[1024];
TCHAR szMsg[1024];
va_list arglist;
va_start(arglist, uFlags);
(void)CchLoadString(wIdString, szFmt, LENGTH(szFmt));
wvsprintf(szMsg, szFmt, arglist);
Assert((int)lstrlen(szMsg) < LENGTH(szMsg));
return MessageBox(GetActiveWindow(), szMsg, szTitle, uFlags);
} // MsgBoxPrintf
/////////////////////////////////////////////////////////////////////////////
int DoDialogBoxParam(UINT wIdDialog, HWND hwndParent, DLGPROC dlgproc, LPARAM lParam)
{
int nResult;
AssertSz(g_hwndModeless == NULL, "NYI");
if (g_hwndModeless != NULL)
{
// If a modeless dialog exists, disable it
Assert(IsWindow(g_hwndModeless));
EnableWindow(g_hwndModeless, FALSE);
}
nResult = ::DialogBoxParam(hInstanceSave,
MAKEINTRESOURCE(wIdDialog), hwndParent, (DLGPROC)dlgproc, lParam);
ReportFSz1(nResult != -1, "Unable to create dialog Id=%d", wIdDialog);
if (g_hwndModeless != NULL)
{
// If a modeless dialog exists, re-enable it
Assert(IsWindow(g_hwndModeless));
// REVIEW: LATER: use fEnableOld instead of TRUE
EnableWindow(g_hwndModeless, TRUE);
}
return nResult;
} // DoDialogBoxParam
/////////////////////////////////////////////////////////////////////////////
int DoPropertySheet(const PROPSHEETHEADER * pPSH)
{
Assert(pPSH);
Assert((pPSH->dwFlags & PSH_MODELESS) == 0);
return PropertySheet(pPSH);
} // DoPropertySheet
/////////////////////////////////////////////////////////////////////////////
int DoModelessPropertySheet(const PROPSHEETHEADER * pPSH)
{
Assert(pPSH);
Assert(pPSH->dwFlags & PSH_MODELESS);
Assert(g_hwndModeless == NULL);
g_hwndModeless = (HWND)PropertySheet(pPSH);
Report(IsWindow(g_hwndModeless));
// Supply MessagePump
// PropSheet_GetCurrentPageHwnd() == NULL is the way
// the propertysheet informs us that the pages have
// accepted termination
MSG msg;
while (PropSheet_GetCurrentPageHwnd(g_hwndModeless) != NULL &&
GetMessage(&msg, NULL, 0,0))
{
if (!PropSheet_IsDialogMessage(g_hwndModeless, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} // while
SideReport(DestroyWindow(g_hwndModeless));
g_hwndModeless = NULL;
return 0;
} // DoModelessPropertySheet
/////////////////////////////////////////////////////////////////////////////
void PropertySheet_InitWindowPos(HWND hwndPropertySheet, int xPos, int yPos)
{
RECT rc;
Assert(IsWindow(hwndPropertySheet));
GetWindowRect(hwndMain, OUT &rc);
SetWindowPos(hwndPropertySheet, NULL,
rc.left + xPos, rc.top + yPos, 0, 0,
SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOZORDER);
} // PropertySheet_InitWindowPos
/////////////////////////////////////////////////////////////////////////////
void LoadStringPrintf(
UINT wIdString, // IN: String Id
TCHAR szBuffer[], // OUT: Buffer to receive the string
int cchBuffer, // IN: Length of buffer (in characters)
...) // IN: Optional arguments
{
TCHAR szT[1024];
va_list arglist;
va_start(arglist, cchBuffer);
(void)CchLoadString(wIdString, szT, LENGTH(szT));
Assert(szBuffer);
wvsprintf(szBuffer, szT, arglist);
Assert((int)lstrlen(szBuffer) < cchBuffer);
} // LoadStringPrintf
/////////////////////////////////////////////////////////////////////////////
// SetWindowString()
//
// Function to load a string and send it to a window
// Typical use:
// SetWindowString(hwndStatic, IDS_MESSAGE);
// SetDlgItemString(hdlg, IDC_STATIC, IDS_MESSAGE);
//
void SetWindowString(HWND hwnd, UINT wIdString)
{
TCHAR szT[1024];
(void)CchLoadString(wIdString, szT, LENGTH(szT));
(void)FSetWindowText(hwnd, szT);
} // SetWindowString
/////////////////////////////////////////////////////////////////////////////
// SetWindowTextPrintf()
//
// Load a string from the resource, format it and send it to
// a window.
// Typical use:
// SetWindowText(hwndStatic, IDS_s_DATA, szDataName);
//
void SetWindowTextPrintf(HWND hwnd, UINT wIdString, ...)
{
TCHAR szBuffer[1024];
TCHAR szT[1024];
va_list arglist;
va_start(arglist, wIdString);
(void)CchLoadString(wIdString, szT, LENGTH(szT));
Assert(szBuffer);
wvsprintf(szBuffer, szT, arglist);
Assert(lstrlen(szBuffer) < LENGTH(szBuffer));
(void)FSetWindowText(hwnd, szBuffer);
} // SetWindowTextPrintf
/////////////////////////////////////////////////////////////////////////////
// dwTime is in seconds
BOOL EditCombo_FGetTime(HWND hdlg, UINT wIdEdit, UINT wIdCombo, OUT DWORD * pdwTime)
{
HWND hwndCombo;
int iCurSel;
DWORD dwTimeValue;
DWORD dwTimeUnits;
Assert(pdwTime);
hwndCombo = HGetDlgItem(hdlg, wIdCombo);
iCurSel = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);
if (iCurSel < 0)
{
Trace0(mskTraceInfo, "\nINFO: EditCombo_GetTime() - No time units selected on combobox");
return FALSE;
}
dwTimeValue = SendMessage(hwndCombo, CB_GETITEMDATA, iCurSel, 0);
Assert(dwTimeValue != 0);
Assert(dwTimeValue != CB_ERR);
if (!FGetCtrlDWordValue(HGetDlgItem(hdlg, wIdEdit), OUT &dwTimeUnits,
0, 0xFFFFFFFF / dwTimeValue))
{
return FALSE;
}
AssertSz((DWORDLONG)dwTimeValue * (DWORDLONG)dwTimeUnits <= 0xFFFFFFFF, "Integer Overflow");
*pdwTime = dwTimeValue * dwTimeUnits;
return TRUE;
} // EditCombo_FGetTime
/////////////////////////////////////////////////////////////////////////////
void EditCombo_SetTime(HWND hdlg, UINT wIdEdit, UINT wIdCombo, IN DWORD dwTime)
{
int iTime = iTimeSeconds;
while ((dwTime % rgdwTimeValue[iTime+1]) == 0)
{
iTime++;
if (iTime >= iTimeYears)
break;
if (dwTime <= rgdwTimeValue[iTime+1])
break;
}
SetCtrlDWordValue(HGetDlgItem(hdlg, wIdEdit), dwTime / rgdwTimeValue[iTime]);
ComboBox_FillListWithTimeUnits(
HGetDlgItem(hdlg, wIdCombo),
iTimeSeconds,
iTimeYears,
iTime);
} // EditCombo_SetTime
/////////////////////////////////////////////////////////////////////////////
// Fill a combobox with time units
void ComboBox_FillListWithTimeUnits(HWND hwndCombo, int iTimeMin, int iTimeMax, int iTimeSelect)
{
TCHAR szT[64];
int iTime;
int i;
AssertClassName(hwndCombo, "ComboBox");
Assert(iTimeMin > 0 && iTimeMax <= iTimeYears);
LSendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);
for (iTime = iTimeMin; iTime <= iTimeMax; iTime++)
{
CchLoadString(IDS_TIME_NIL + iTime, szT, LENGTH(szT));
i = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)szT);
Report(i >= 0);
LSendMessage(hwndCombo, CB_SETITEMDATA, i, rgdwTimeValue[iTime]);
if (iTime == iTimeSelect)
SendMessage(hwndCombo, CB_SETCURSEL, i, 0);
}
} // ComboBox_FillListWithTimeUnits
/////////////////////////////////////////////////////////////////////////////
LPARAM ComboBox_GetSelectedItemData(HWND hwndComboBox)
{
LONG l;
Assert(IsWindow(hwndComboBox));
l = LSendMessage(hwndComboBox, CB_GETCURSEL, 0, 0);
AssertSz(l != CB_ERR, "Combobox has no item selected");
l = LSendMessage(hwndComboBox, CB_GETITEMDATA, l, 0);
AssertSz(l != CB_ERR, "Cannot extract item data from combobox");
if (l == CB_ERR)
return NULL;
return l;
} // ComboBox_GetSelectedItemData
/////////////////////////////////////////////////////////////////////////////
int ComboBox_FindItemData(HWND hwndComboBox, LPARAM lParamData)
{
Assert(IsWindow(hwndComboBox));
Trace0(lParamData == CB_ERR ? mskTraceWarnings : mskTraceNone,
"\nWARNING: lParamData==CB_ERR - Very confusing parameter.");
int iItem;
iItem = LSendMessage(hwndComboBox, CB_GETCOUNT, 0, 0);
Assert(iItem >= 0);
while (iItem-- > 0)
{
LRESULT l = LSendMessage(hwndComboBox, CB_GETITEMDATA, iItem, 0);
Assert(l != CB_ERR);
if (l == lParamData)
return iItem;
}
return -1;
} // ComboBox_FindItemData
/////////////////////////////////////////////////////////////////////////////
LPARAM ListBox_GetSelectedItemData(HWND hwndListBox)
{
LONG l;
Assert(IsWindow(hwndListBox));
l = LSendMessage(hwndListBox, LB_GETCURSEL, 0, 0);
AssertSz(l != LB_ERR, "Listbox has no item selected");
l = LSendMessage(hwndListBox, LB_GETITEMDATA, l, 0);
AssertSz(l != LB_ERR, "Cannot extract item data from listbox");
if (l == LB_ERR)
return NULL;
return l;
} // ListBox_GetSelectedItemData
/////////////////////////////////////////////////////////////////////////////
int ListBox_FindItemData(HWND hwndListBox, LPARAM lParamData)
{
Assert(IsWindow(hwndListBox));
Trace0(lParamData == LB_ERR ? mskTraceWarnings : mskTraceNone,
"\nWARNING: lParamData==LB_ERR - Very confusing parameter.");
int iItem;
iItem = LSendMessage(hwndListBox, LB_GETCOUNT, 0, 0);
Assert(iItem >= 0);
while (iItem-- > 0)
{
LRESULT l = LSendMessage(hwndListBox, LB_GETITEMDATA, iItem, 0);
Assert(l != LB_ERR);
if (l == lParamData)
return iItem;
}
return -1;
} // ListBox_FindItemData
/////////////////////////////////////////////////////////////////////////////
void DoPopupMenu(UINT wIdMenu, HWND hwndParent)
{
HMENU hMenu;
POINT pt;
hMenu = HLoadMenu(wIdMenu);
Report(hMenu);
Report(GetSubMenu(hMenu, 0));
if (hwndParent == NULL)
hwndParent = hwndMain;
Assert(IsWindow(hwndParent));
GetCursorPos(&pt);
TrackPopupMenu(
GetSubMenu(hMenu, 0),
0,
pt.x,
pt.y,
0,
hwndParent,
NULL);
SideReport(DestroyMenu(hMenu));
} // DoPopupMenu
/////////////////////////////////////////////////////////////////////////////
void DoContextMenu(int iSubMenu, POINT ptMenu)
{
AssertSz1(GetSubMenu(hmenuContext, iSubMenu), "SubMenu[%d] does not exists", iSubMenu);
Assert(IsWindow(GetActiveWindow()));
TrackPopupMenu(
GetSubMenu(hmenuContext, iSubMenu),
TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
ptMenu.x, ptMenu.y,
0, hwndMain, NULL);
//0, GetActiveWindow(), NULL);
} // DoContextMenu
/////////////////////////////////////////////////////////////////////////////
void GetChildRect(HWND hwndChild, OUT RECT * prcChild)
{
Assert(IsWindow(hwndChild));
Assert(prcChild != NULL);
Assert(IsWindow(GetParent(hwndChild)));
GetWindowRect(hwndChild, OUT prcChild);
MapWindowPoints(HWND_DESKTOP, GetParent(hwndChild), INOUT (POINT*)prcChild, 2);
} // GetChildRect
/////////////////////////////////////////////////////////////////////////////
void SetChildRect(HWND hwndChild, IN RECT * prcChild)
{
Assert(IsWindow(hwndChild));
Assert(prcChild != NULL);
SetWindowPos(hwndChild, NULL,
prcChild->left, prcChild->top,
prcChild->right - prcChild->left, prcChild->bottom - prcChild->top,
SWP_NOACTIVATE | SWP_NOZORDER);
} // SetChildRect
/////////////////////////////////////////////////////////////////////////////
// FStripSpaces()
//
// Strip leading and trailing spaces from the string.
// Return TRUE if spaces has been removed, otherwise FALSE.
//
BOOL FStripSpaces(INOUT TCHAR szString[])
{
TCHAR * pchSrc;
TCHAR * pch;
Assert(szString);
if (szString[0] == 0)
return FALSE;
pchSrc = szString;
if (*pchSrc == ' ')
{
while (*pchSrc == ' ')
pchSrc++;
pch = szString;
do
{
*pch++ = *pchSrc++;
}
while (*pchSrc);
while (pch > szString && *(pch - 1) == ' ')
pch--;
*pch = 0;
return TRUE;
}
pch = szString + strlen(szString);
Assert(pch > szString);
if (*(pch - 1) != ' ')
return FALSE;
while (pch > szString && *(pch - 1) == ' ')
pch--;
*pch = 0;
return TRUE;
} // FStripSpaces
/////////////////////////////////////////////////////////////////////////////
// FAsciiSzToDWord()
//
// Convert a string to a binary integer
// Set gGI_dwFlags to its default flags.
// Default flags:
// - String is allowed to be decimal or hexadecimal
// - Minus sign is allowed
// If successful, set *pdwValue to the integer and return TRUE.
// If not successful, set gGI_dwFlags to the error code and
// return FALSE.
// NOTE: gGI_pchLast points to the last character parsed regardless
// of the result. You may use gGI_pchLast to parse the rest of the
// string.
//
BOOL FAsciiSzToDWord(const TCHAR szNum[], OUT DWORD * pdwValue)
{
DWORD dwResult = 0;
UINT iBase = 10; // Assume a decimal base
BOOL fIsEmpty = TRUE; // String is empty
BOOL fNegative = FALSE; // No minus sign found yet
DWORD dwFlags = gGI_dwFlags; // Keep a copy of the flags
Assert(szNum);
Assert(pdwValue);
*pdwValue = 0;
gGI_dwFlags &= ~GI_mskErr; // Clear the last error (if any)
if (gGI_dwFlags & GI_mskfAutoResetToDefault)
gGI_dwFlags = gGI_dwFlagsAutoReset; // Set the flags for the next time
gGI_pchLast = (TCHAR *)szNum;
// Skip leading blanks
while (*gGI_pchLast == _W' ')
gGI_pchLast++;
// Check for a minus sign
if (*gGI_pchLast == _W'-')
{
if ((dwFlags & GI_mskfAllowMinusSign) == 0)
{
gGI_dwFlags |= GI_mskfErrMinusSignFound;
return FALSE;
}
fNegative = TRUE;
gGI_pchLast++;
}
// Skip leading zeroes
while (*gGI_pchLast == _W'0')
{
gGI_pchLast++;
fIsEmpty = FALSE;
}
// Check if we are using hexadecimal base
if (*gGI_pchLast == _W'x' || *gGI_pchLast == _W'X')
{
if ((dwFlags & GI_mskfAllowHexDigit) == 0)
{
gGI_dwFlags |= GI_mskfErrHexDigitFound;
return FALSE;
}
iBase = 16;
gGI_pchLast++;
fIsEmpty = TRUE;
}
while (*gGI_pchLast != 0)
{
if (*gGI_pchLast == _W' ')
break;
// Search the character in the hexadecimal string
char const * const pchDigit = strchr(g_rgchHex, *gGI_pchLast);
if (pchDigit == NULL)
{
// Character is not found
if (dwFlags & GI_mskfAllowRandomTail)
break;
gGI_dwFlags |= GI_mskfErrIllegalDigitFound;
return FALSE;
}
int iDigit = (pchDigit - g_rgchHex) >> 1;
if (iDigit >= (int)iBase)
{
// Hexadecimal character in a decimal integer
if (dwFlags & GI_mskfAllowRandomTail)
break;
gGI_dwFlags |= GI_mskfErrHexDigitFound;
return FALSE;
}
fIsEmpty = FALSE;
dwResult = (dwResult * iBase) + iDigit;
if (dwResult < *pdwValue)
{
gGI_dwFlags |= GI_mskfErrIntegerOverflow;
return FALSE;
}
*pdwValue = dwResult;
gGI_pchLast++;
} // while
if (fIsEmpty && ((dwFlags & GI_mskfEmptyStringValid) == 0))
{
// String is empty while an empty string is not valid
Assert(dwResult == 0);
gGI_dwFlags |= GI_mskfErrEmptyStringFound;
return FALSE;
}
if (fNegative)
{
// C4146: unary minus operator applied to unsigned type, result still unsigned
#pragma warning (disable : 4146)
*pdwValue = -dwResult;
#pragma warning (default : 4146)
}
if (dwFlags & GI_mskfCheckForEmptyTail)
{
// Spaces at the tail are allowed
while (*gGI_pchLast == _W' ')
gGI_pchLast++;
if (*gGI_pchLast != 0)
{
gGI_dwFlags |= GI_mskfErrTailNotEmpty;
return FALSE;
}
} // if
return TRUE;
} // FAsciiSzToDWord
/////////////////////////////////////////////////////////////////////////////
// FGetCtrlDWordValue()
//
// Return a 32-bit unsigned integer from an edit control
//
// This function is like GetDlgItemInt() but accepts hexadecimal values,
// has range checking and overflow checking.
// If value is out of range, function will display a friendly message and will
// set the focus to control.
// Range: dwMin to dwMax inclusive
// - If both dwMin and dwMax are zero, => silent mode (no dialog will appear if
// number is not valid)
// - Return TRUE if successful, otherwise FALSE
// - On error, pdwValue remains unchanged.
//
BOOL FGetCtrlDWordValue(HWND hwndEdit, OUT DWORD * pdwValue, DWORD dwMin, DWORD dwMax)
{
TCHAR szT[64];
DWORD dwResult;
BOOL fSilent;
BOOL fCheckRange;
int idsError;
Assert(IsWindow(hwndEdit));
Assert(pdwValue);
Assert(dwMin <= dwMax);
fCheckRange = (dwMin | dwMax);
fSilent = (gGI_dwFlags & GI_mskfSilentMode) | !fCheckRange;
idsError = 0;
CchGetWindowText(hwndEdit, OUT szT, LENGTH(szT));
if (!FAsciiSzToDWord(szT, OUT &dwResult))
{
Assert(gGI_dwFlags & GI_mskErr);
if (gGI_dwFlags & GI_mskfErrIntegerOverflow)
{
idsError = IDS_ERR_INTEGEROVERFLOW;
}
else
{
// Syntax error
idsError = IDS_ERR_ENTERVALIDNUMBER;
}
}
else
{
Assert((gGI_dwFlags & GI_mskErr) == 0);
if (fCheckRange && ((dwResult < dwMin) || (dwResult > dwMax)))
{
// Out of range
idsError = IDS_ERR_uu_INTEGETOOLARGE;
}
}
if (idsError)
{
if (!fSilent)
{
MsgBoxPrintf(idsError, szCaptionApp, MB_ICONEXCLAMATION | MB_OK,
dwMin, dwMax);
SetFocus(hwndEdit);
}
return FALSE;
}
*pdwValue = dwResult;
return TRUE;
} // FGetCtrlDWordValue
/////////////////////////////////////////////////////////////////////////////
// FGetRadioSelection()
//
// Return either 1 or 2 depending on which of the 2 radio buttons is selected.
//
// If neither is selected, function will display a friendly message and will
// set the focus to control.
// - CtrlOne, CtrlTwo: Crtl Ids of the radio buttons
// - Return TRUE if successful, otherwise FALSE
// - On error, pdwValue remains unchanged.
//
BOOL FGetRadioSelection(HWND hdlg, int CtrlOne, int CtrlTwo, OUT DWORD * pdwValue)
{
int Button1State, Button2State;
Assert(pdwValue);
Button1State = IsDlgButtonChecked ( hdlg, CtrlOne);
Button2State = IsDlgButtonChecked ( hdlg, CtrlTwo);
AssertSz (Button1State != Button2State, "Neither button is checked.");
*pdwValue = Button1State ? 1 : 2;
return TRUE;
} // FGetRadioSelection
/////////////////////////////////////////////////////////////////////////////
void SetCtrlDWordValue(HWND hwnd, DWORD dwValue)
{
TCHAR szT[32];
Assert(IsWindow(hwnd));
wsprintf(szT, _W"%u", dwValue);
Assert(lstrlen(szT) < sizeof(szT));
FSetWindowText(hwnd, szT);
} // SetCtrlDWordValue
/////////////////////////////////////////////////////////////////////////////
// FStringToRawData()
//
// - Convert a string to an array of byte
// - Return TRUE if convertion is successful
// - Return FALSE if an illegal character is found and
// set cbRawData to the index of the illegal character in szString.
// - cbRawData is the number of bytes in rgbRawData; it does include
// the null terminator from szString.
//
// This function behave more like typing strings in C/C++.
// - Support non printable characters: \n, \r, \t, \\, \xXX, \NNN
// eg: "\nFooBar\t\x2C\15" => { 0x0A, 'F', 'o', 'o', 0x09, 'B', 'a', 'r', 0x2C, 0x0F, 0x00 }
//
BOOL FStringToRawData(
IN const char szString[],
OUT BYTE rgbRawData[],
INOUT int * pcbRawData) // IN: Number of bytes in rgbRawData (OUT: ichStringError if an error occur )
{
DWORD dwT;
char szT[16];
const char * pchSrc = szString;
BYTE * pbDest = rgbRawData;
Assert(szString != NULL);
Assert(rgbRawData != NULL);
Assert(pcbRawData != NULL);
AssertSz((int)strlen(szString) < *pcbRawData, "Buffer rgbRawData too small");
while (*pchSrc)
{
if (*pchSrc != '\\')
{
*pbDest++ = *pchSrc++;
continue;
}
switch (*++pchSrc)
{
case 'n':
*pbDest++ = '\n';
break;
case 'r':
*pbDest++ = '\r';
break;
case 't':
*pbDest++ = '\t';
break;
case '\\':
*pbDest++ = '\\';
break;
case 'x':
szT[0] = 'x';
if (*++pchSrc == 0)
{
// End of string found
*pcbRawData = (pchSrc - szString);
return FALSE;
}
szT[1] = *pchSrc++;
szT[2] = 0;
if (*pchSrc != 0 && strchr(g_rgchHex, *pchSrc) != NULL)
{
szT[2] = *pchSrc++;
szT[3] = 0;
}
gGI_dwFlags = GI_mskfAllowHexDigit | GI_mskfAutoResetToDefault;
if (!FAsciiSzToDWord(szT, OUT &dwT))
{
Assert(gGI_dwFlags & GI_mskErr);
*pcbRawData = (pchSrc - szString - 2);
return FALSE;
}
Assert((gGI_dwFlags & GI_mskErr) == 0);
Assert(gGI_pchLast != NULL);
Assert(*gGI_pchLast == 0);
Assert(dwT <= 255);
*pbDest++ = (BYTE)dwT;
continue;
default:
gGI_dwFlags = GI_mskfAllowRandomTail | GI_mskfAutoResetToDefault;
if (!FAsciiSzToDWord(pchSrc, OUT &dwT))
{
Assert(gGI_dwFlags & GI_mskErr);
*pcbRawData = (pchSrc - szString);
return FALSE;
}
Assert((gGI_dwFlags & GI_mskErr) == 0);
Assert(gGI_pchLast != NULL);
if (dwT > 255)
{
*pcbRawData = (pchSrc - szString);
return FALSE;
}
*pbDest++ = (BYTE)dwT;
pchSrc = gGI_pchLast;
continue;
} // switch
pchSrc++;
} // while
*pcbRawData = pbDest - rgbRawData;
*pbDest = 0;
return TRUE;
} // FStringToRawData
/////////////////////////////////////////////////////////////////////////////
// RawDataToString()
//
// Convert an array of bytes into a human-readable string
// The return value is the number of characters stored in the output buffer,
// not counting the terminating null character.
//
int RawDataToString(
IN const BYTE rgbRawData[],
IN int cbRawData,
OUT char szString[],
IN int cchStringMax) // Size of the buffer
{
const BYTE * pbSrc = rgbRawData;
char * pchDest = szString;
Assert(rgbRawData != NULL);
Assert(szString != NULL);
AssertSz(cbRawData <= cchStringMax, "Buffer szString too small, string will be truncated");
while (cbRawData--)
{
if (pchDest - szString > cchStringMax - 5)
{
DebugCode( *pchDest = 0; )
Trace1(mskTraceAlways, "\nINFO: RawDataToString(): Output buffer szString too small - "
"String %s truncated", szString);
break;
}
if (*pbSrc >= ' ' && *pbSrc <= '~')
{
if (*pbSrc != '\\')
{
*pchDest++ = *pbSrc++;
continue;
}
}
switch (*pbSrc++)
{
case '\n':
*pchDest++ = '\\';
*pchDest++ = 'n';
break;
case '\r':
*pchDest++ = '\\';
*pchDest++ = 'r';
break;
case '\t':
*pchDest++ = '\\';
*pchDest++ = 't';
break;
case '\\':
*pchDest++ = '\\';
*pchDest++ = '\\';
break;
default:
pchDest += wsprintf(pchDest, "\\x%X", *(pbSrc-1));
} // switch
} // while
// Append null terminator
*pchDest = 0;
return (pchDest - szString);
} // RawDataToString
/////////////////////////////////////////////////////////////////////////////
// RevIpAddrOrder()
//
// Reverses the octet order of an IP addr or a partial IP addr.
//
UINT
RevIpAddrOrder(const char * pszInAddr, char * pszOutAddr)
{
char * pchSrc;
char * pchDest;
pchDest = pszOutAddr;
pchSrc = (char *)&pszInAddr[strlen(pszInAddr) - 1];
int ccOctetLen;
BOOL done = FALSE;
while (!done) {
ccOctetLen = 0;
while ((*pchSrc != '.') && (pchSrc > pszInAddr)){
pchSrc--;
ccOctetLen++;
}
if (pchSrc == pszInAddr) {
done = TRUE;
ccOctetLen++;
} else {
pchSrc++;
}
strncpy (pchDest, pchSrc, ccOctetLen);
pchDest += ccOctetLen;
if (!done) {
*pchDest = '.';
}
++pchDest;
pchSrc -= 2;
}
pszOutAddr[strlen(pszInAddr)] = '\0'; // NULL Terminate it
return (strlen (pszOutAddr));
}