234 lines
5.1 KiB
C++
234 lines
5.1 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
partialassemblyversion.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Class describing a partial/wildcarded assembly version.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Michael J. Grier (MGrier) 13-May-2000
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "stdinc.h"
|
||
|
#include <windows.h>
|
||
|
#include "sxsp.h"
|
||
|
#include "partialassemblyversion.h"
|
||
|
|
||
|
BOOL
|
||
|
CPartialAssemblyVersion::Parse(
|
||
|
PCWSTR sz,
|
||
|
SIZE_T Cch
|
||
|
)
|
||
|
{
|
||
|
BOOL fSuccess = FALSE;
|
||
|
ULONG cDots = 0;
|
||
|
PCWSTR pszTemp;
|
||
|
SIZE_T CchLeft;
|
||
|
USHORT usTemp;
|
||
|
ASSEMBLY_VERSION avTemp;
|
||
|
PCWSTR pszLast;
|
||
|
BOOL MajorSpecified = FALSE;
|
||
|
BOOL MinorSpecified = FALSE;
|
||
|
BOOL BuildSpecified = FALSE;
|
||
|
BOOL RevisionSpecified = FALSE;
|
||
|
|
||
|
// Somehow people often leave trailing nulls; we'll just back off Cch in this case.
|
||
|
while ((Cch != 0) && (sz[Cch - 1] == L'\0'))
|
||
|
Cch--;
|
||
|
|
||
|
avTemp.Major = 0;
|
||
|
avTemp.Minor = 0;
|
||
|
avTemp.Revision = 0;
|
||
|
avTemp.Build = 0;
|
||
|
|
||
|
// "*" means everything unspecified...
|
||
|
if ((Cch == 1) && (sz[0] == L'*'))
|
||
|
{
|
||
|
m_MajorSpecified = FALSE;
|
||
|
m_MinorSpecified = FALSE;
|
||
|
m_BuildSpecified = FALSE;
|
||
|
m_RevisionSpecified = FALSE;
|
||
|
|
||
|
fSuccess = TRUE;
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
pszTemp = sz;
|
||
|
CchLeft = Cch;
|
||
|
|
||
|
while (CchLeft-- != 0)
|
||
|
{
|
||
|
WCHAR wch = *pszTemp++;
|
||
|
|
||
|
if (wch == L'.')
|
||
|
{
|
||
|
cDots++;
|
||
|
|
||
|
if (cDots >= 4)
|
||
|
{
|
||
|
::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
|
||
|
goto Exit;
|
||
|
}
|
||
|
}
|
||
|
else if ((wch != L'*') && ((wch < L'0') || (wch > L'9')))
|
||
|
{
|
||
|
::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
|
||
|
goto Exit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (cDots < 3)
|
||
|
{
|
||
|
::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
pszTemp = sz;
|
||
|
pszLast = sz + Cch;
|
||
|
|
||
|
usTemp = 0;
|
||
|
for (;;)
|
||
|
{
|
||
|
WCHAR wch = *pszTemp++;
|
||
|
|
||
|
if (wch == L'*')
|
||
|
{
|
||
|
// If there's been a previous digit, we can't then have a * (there's no matching version number "5*")
|
||
|
if (MajorSpecified)
|
||
|
{
|
||
|
::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
if (*pszTemp != L'.')
|
||
|
{
|
||
|
::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (wch == L'.')
|
||
|
break;
|
||
|
|
||
|
usTemp = (usTemp * 10) + (wch - L'0');
|
||
|
MajorSpecified = TRUE;
|
||
|
}
|
||
|
avTemp.Major = usTemp;
|
||
|
|
||
|
usTemp = 0;
|
||
|
for (;;)
|
||
|
{
|
||
|
WCHAR wch = *pszTemp++;
|
||
|
|
||
|
if (wch == L'*')
|
||
|
{
|
||
|
// If there's been a previous digit, we can't then have a * (there's no matching version number "5*")
|
||
|
if (MinorSpecified)
|
||
|
{
|
||
|
::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
if (*pszTemp != L'.')
|
||
|
{
|
||
|
::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (wch == L'.')
|
||
|
break;
|
||
|
|
||
|
usTemp = (usTemp * 10) + (wch - L'0');
|
||
|
MinorSpecified = TRUE;
|
||
|
}
|
||
|
avTemp.Minor = usTemp;
|
||
|
|
||
|
usTemp = 0;
|
||
|
for (;;)
|
||
|
{
|
||
|
WCHAR wch = *pszTemp++;
|
||
|
|
||
|
if (wch == L'*')
|
||
|
{
|
||
|
// If there's been a previous digit, we can't then have a * (there's no matching version number "5*")
|
||
|
if (RevisionSpecified)
|
||
|
{
|
||
|
::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
if (*pszTemp != L'.')
|
||
|
{
|
||
|
::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (wch == L'.')
|
||
|
break;
|
||
|
|
||
|
usTemp = (usTemp * 10) + (wch - L'0');
|
||
|
RevisionSpecified = TRUE;
|
||
|
}
|
||
|
avTemp.Revision = usTemp;
|
||
|
|
||
|
// Now the tricky bit. We aren't necessarily null-terminated, so we
|
||
|
// have to just look for hitting the end.
|
||
|
usTemp = 0;
|
||
|
while (pszTemp < pszLast)
|
||
|
{
|
||
|
WCHAR wch = *pszTemp++;
|
||
|
|
||
|
if (wch == L'*')
|
||
|
{
|
||
|
// If there's been a previous digit, we can't then have a * (there's no matching version number "5*")
|
||
|
if (MajorSpecified)
|
||
|
{
|
||
|
::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
// If that wasn't the last character, it was wrong.
|
||
|
if (pszTemp < pszLast)
|
||
|
{
|
||
|
::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
usTemp = (usTemp * 10) + (wch - L'0');
|
||
|
BuildSpecified = TRUE;
|
||
|
}
|
||
|
avTemp.Build = usTemp;
|
||
|
|
||
|
m_AssemblyVersion = avTemp;
|
||
|
|
||
|
m_MajorSpecified = MajorSpecified;
|
||
|
m_MinorSpecified = MinorSpecified;
|
||
|
m_RevisionSpecified = RevisionSpecified;
|
||
|
m_BuildSpecified = BuildSpecified;
|
||
|
|
||
|
fSuccess = TRUE;
|
||
|
|
||
|
Exit:
|
||
|
return fSuccess;
|
||
|
}
|