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.

233 lines
5.4 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. partialassemblyversion.cpp
  5. Abstract:
  6. Class describing a partial/wildcarded assembly version.
  7. Author:
  8. Michael J. Grier (MGrier) 13-May-2000
  9. Revision History:
  10. --*/
  11. #include "stdinc.h"
  12. #include <windows.h>
  13. #include "sxsp.h"
  14. #include "partialassemblyversion.h"
  15. BOOL
  16. CPartialAssemblyVersion::Parse(
  17. PCWSTR sz,
  18. SIZE_T Cch
  19. )
  20. {
  21. BOOL fSuccess = FALSE;
  22. ULONG cDots = 0;
  23. PCWSTR pszTemp;
  24. SIZE_T CchLeft;
  25. USHORT usTemp;
  26. ASSEMBLY_VERSION avTemp;
  27. PCWSTR pszLast;
  28. BOOL MajorSpecified = FALSE;
  29. BOOL MinorSpecified = FALSE;
  30. BOOL BuildSpecified = FALSE;
  31. BOOL RevisionSpecified = FALSE;
  32. // Somehow people often leave trailing nulls; we'll just back off Cch in this case.
  33. while ((Cch != 0) && (sz[Cch - 1] == L'\0'))
  34. Cch--;
  35. avTemp.Major = 0;
  36. avTemp.Minor = 0;
  37. avTemp.Revision = 0;
  38. avTemp.Build = 0;
  39. // "*" means everything unspecified...
  40. if ((Cch == 1) && (sz[0] == L'*'))
  41. {
  42. m_MajorSpecified = FALSE;
  43. m_MinorSpecified = FALSE;
  44. m_BuildSpecified = FALSE;
  45. m_RevisionSpecified = FALSE;
  46. fSuccess = TRUE;
  47. goto Exit;
  48. }
  49. pszTemp = sz;
  50. CchLeft = Cch;
  51. while (CchLeft-- != 0)
  52. {
  53. WCHAR wch = *pszTemp++;
  54. if (wch == L'.')
  55. {
  56. cDots++;
  57. if (cDots >= 4)
  58. {
  59. ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
  60. goto Exit;
  61. }
  62. }
  63. else if ((wch != L'*') && ((wch < L'0') || (wch > L'9')))
  64. {
  65. ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
  66. goto Exit;
  67. }
  68. }
  69. if (cDots < 3)
  70. {
  71. ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
  72. goto Exit;
  73. }
  74. pszTemp = sz;
  75. pszLast = sz + Cch;
  76. usTemp = 0;
  77. for (;;)
  78. {
  79. WCHAR wch = *pszTemp++;
  80. if (wch == L'*')
  81. {
  82. // If there's been a previous digit, we can't then have a * (there's no matching version number "5*")
  83. if (MajorSpecified)
  84. {
  85. ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
  86. goto Exit;
  87. }
  88. if (*pszTemp != L'.')
  89. {
  90. ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
  91. goto Exit;
  92. }
  93. break;
  94. }
  95. if (wch == L'.')
  96. break;
  97. usTemp = (usTemp * 10) + (wch - L'0');
  98. MajorSpecified = TRUE;
  99. }
  100. avTemp.Major = usTemp;
  101. usTemp = 0;
  102. for (;;)
  103. {
  104. WCHAR wch = *pszTemp++;
  105. if (wch == L'*')
  106. {
  107. // If there's been a previous digit, we can't then have a * (there's no matching version number "5*")
  108. if (MinorSpecified)
  109. {
  110. ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
  111. goto Exit;
  112. }
  113. if (*pszTemp != L'.')
  114. {
  115. ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
  116. goto Exit;
  117. }
  118. break;
  119. }
  120. if (wch == L'.')
  121. break;
  122. usTemp = (usTemp * 10) + (wch - L'0');
  123. MinorSpecified = TRUE;
  124. }
  125. avTemp.Minor = usTemp;
  126. usTemp = 0;
  127. for (;;)
  128. {
  129. WCHAR wch = *pszTemp++;
  130. if (wch == L'*')
  131. {
  132. // If there's been a previous digit, we can't then have a * (there's no matching version number "5*")
  133. if (RevisionSpecified)
  134. {
  135. ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
  136. goto Exit;
  137. }
  138. if (*pszTemp != L'.')
  139. {
  140. ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
  141. goto Exit;
  142. }
  143. break;
  144. }
  145. if (wch == L'.')
  146. break;
  147. usTemp = (usTemp * 10) + (wch - L'0');
  148. RevisionSpecified = TRUE;
  149. }
  150. avTemp.Revision = usTemp;
  151. // Now the tricky bit. We aren't necessarily null-terminated, so we
  152. // have to just look for hitting the end.
  153. usTemp = 0;
  154. while (pszTemp < pszLast)
  155. {
  156. WCHAR wch = *pszTemp++;
  157. if (wch == L'*')
  158. {
  159. // If there's been a previous digit, we can't then have a * (there's no matching version number "5*")
  160. if (MajorSpecified)
  161. {
  162. ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
  163. goto Exit;
  164. }
  165. // If that wasn't the last character, it was wrong.
  166. if (pszTemp < pszLast)
  167. {
  168. ::FusionpSetLastWin32Error(ERROR_SXS_MANIFEST_PARSE_ERROR);
  169. goto Exit;
  170. }
  171. break;
  172. }
  173. usTemp = (usTemp * 10) + (wch - L'0');
  174. BuildSpecified = TRUE;
  175. }
  176. avTemp.Build = usTemp;
  177. m_AssemblyVersion = avTemp;
  178. m_MajorSpecified = MajorSpecified;
  179. m_MinorSpecified = MinorSpecified;
  180. m_RevisionSpecified = RevisionSpecified;
  181. m_BuildSpecified = BuildSpecified;
  182. fSuccess = TRUE;
  183. Exit:
  184. return fSuccess;
  185. }