Leaked source code of windows server 2003
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.
 
 
 
 
 
 

267 lines
6.2 KiB

#include "stdinc.h"
#include "debmacro.h"
#include "ntdef.h"
#include "fusionparser.h"
#include "shlwapi.h"
#if !defined(NUMBER_OF)
#define NUMBER_OF(x) (sizeof(x) / sizeof((x)[0]))
#endif
BOOL
CFusionParser::ParseVersion(
ASSEMBLY_VERSION &rav,
PCWSTR sz,
SIZE_T cch,
bool &rfSyntaxValid
)
{
FN_PROLOG_WIN32
ULONG cDots = 0;
PCWSTR pszTemp;
SIZE_T cchLeft;
ULONG ulTemp = 0;
ASSEMBLY_VERSION avTemp;
PCWSTR pszLast;
bool fSyntaxValid = true;
rfSyntaxValid = false;
PARAMETER_CHECK((sz != NULL) || (cch == 0));
avTemp.Major = 0;
avTemp.Minor = 0;
avTemp.Revision = 0;
avTemp.Build = 0;
while ((cch != 0) && (sz[cch - 1] == L'\0'))
cch--;
// Unfortunately there isn't a StrChrN(), so we'll look for the dots ourselves...
pszTemp = sz;
cchLeft = cch;
while (cchLeft-- != 0)
{
WCHAR wch = *pszTemp++;
if (wch == L'.')
{
cDots++;
if (cDots >= 4)
{
fSyntaxValid = false;
break;
}
}
else if ((wch < L'0') || (wch > L'9'))
{
fSyntaxValid = false;
break;
}
}
if (fSyntaxValid && (cDots < 3))
fSyntaxValid = false;
//
// CODECLEANUP:2002-3-29:jonwis - I think we could be better here if we used a
// slightly smarter parsing logic, like "knowing which version slot we're
// parsing for" rather than four for(;;) loops... In the current world,
// we're probably likely to fall off the end of our allocation at some
// point or another..
//
// NTRAID#NTBUG9 - 538512 - jonwis - 2002/04/25 - Request for smarter parser
if (fSyntaxValid)
{
pszTemp = sz;
pszLast = sz + cch;
ulTemp = 0;
for (;;)
{
WCHAR wch = *pszTemp++;
if (wch == L'.')
break;
ulTemp = (ulTemp * 10) + (wch - L'0');
if (ulTemp > 65535)
{
// rfSyntaxValid implicitly false
ASSERT(!rfSyntaxValid);
FN_SUCCESSFUL_EXIT();
}
}
avTemp.Major = (USHORT) ulTemp;
ulTemp = 0;
for (;;)
{
WCHAR wch = *pszTemp++;
if (wch == L'.')
break;
ulTemp = (ulTemp * 10) + (wch - L'0');
if (ulTemp > 65535)
{
// rfSyntaxValid implicitly false
ASSERT(!rfSyntaxValid);
FN_SUCCESSFUL_EXIT();
}
}
avTemp.Minor = (USHORT) ulTemp;
ulTemp = 0;
for (;;)
{
WCHAR wch = *pszTemp++;
if (wch == L'.')
break;
ulTemp = (ulTemp * 10) + (wch - L'0');
if (ulTemp > 65535)
{
// rfSyntaxValid implicitly false
ASSERT(!rfSyntaxValid);
FN_SUCCESSFUL_EXIT();
}
}
avTemp.Revision = (USHORT) ulTemp;
// Now the tricky bit. We aren't necessarily null-terminated, so we
// have to just look for hitting the end.
ulTemp = 0;
while (pszTemp < pszLast)
{
WCHAR wch = *pszTemp++;
ulTemp = (ulTemp * 10) + (wch - L'0');
if (ulTemp > 65535)
{
// rfSyntaxValid implicitly false
ASSERT(!rfSyntaxValid);
FN_SUCCESSFUL_EXIT();
}
}
avTemp.Build = (USHORT) ulTemp;
rav = avTemp;
}
rfSyntaxValid = fSyntaxValid;
FN_EPILOG
}
BOOL
CFusionParser::ParseULONG(
ULONG &rul,
PCWSTR sz,
SIZE_T cch,
ULONG Radix
)
{
BOOL fSuccess = FALSE;
FN_TRACE_WIN32(fSuccess);
ULONG ulTemp = 0;
PARAMETER_CHECK((Radix >= 2) && (Radix <= 36));
while (cch != 0)
{
const WCHAR wch = *sz++;
ULONG Digit = 0;
cch--;
if ((wch >= L'0') && (wch <= L'9'))
Digit = (wch - L'0');
else if ((wch >= L'a') && (wch <= L'z'))
Digit = (10 + wch - L'a');
else if ((wch >= L'A') && (wch <= L'Z'))
Digit = (10 + wch - L'A');
else
ORIGINATE_WIN32_FAILURE_AND_EXIT(InvalidDigit, ERROR_SXS_MANIFEST_PARSE_ERROR);
if (Digit >= Radix)
ORIGINATE_WIN32_FAILURE_AND_EXIT(InvalidDigitForRadix, ERROR_SXS_MANIFEST_PARSE_ERROR);
//
// Simple overflow detection - if the new number is less than the current, oops.
//
// NTRAID#NTBUG9 - 538512 - jonwis - 2002/04/25 - Better overflow detection requested
if (((ulTemp * Radix) + Digit) < ulTemp)
{
ORIGINATE_WIN32_FAILURE_AND_EXIT(CFusionParser::ParseULONG::Overflow, ERROR_ARITHMETIC_OVERFLOW);
}
ulTemp = (ulTemp * Radix) + Digit;
}
rul = ulTemp;
fSuccess = TRUE;
Exit:
return fSuccess;
}
BOOL
FusionDupString(
LPWSTR *ppszOut,
PCWSTR szIn,
SIZE_T cchIn
)
{
BOOL fSuccess = FALSE;
FN_TRACE_WIN32(fSuccess);
if (ppszOut != NULL)
*ppszOut = NULL;
PARAMETER_CHECK((cchIn == 0) || (szIn != NULL));
PARAMETER_CHECK(ppszOut != NULL);
IFALLOCFAILED_EXIT(*ppszOut = FUSION_NEW_ARRAY(WCHAR, cchIn + 1));
if (cchIn != 0)
memcpy(*ppszOut, szIn, cchIn * sizeof(WCHAR));
(*ppszOut)[cchIn] = L'\0';
fSuccess = TRUE;
Exit:
return fSuccess;
}
int SxspHexDigitToValue(WCHAR wch)
{
if ((wch >= L'a') && (wch <= L'f'))
return 10 + (wch - L'a');
else if ((wch >= L'A') && (wch <= 'F'))
return 10 + (wch - L'A');
else if (wch >= '0' && wch <= '9')
return (wch - L'0');
else
return -1;
}
bool SxspIsHexDigit(WCHAR wch)
{
return (((wch >= L'0') && (wch <= L'9')) ||
((wch >= L'a') && (wch <= L'f')) ||
((wch >= L'A') && (wch <= L'F')));
}