Source code of Windows XP (NT5)
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.

300 lines
9.5 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1996-1997, Microsoft Corporation.
  4. //
  5. // File: varutil.cxx
  6. //
  7. // Contents: Utilities for variable replacement
  8. //
  9. // History: 96/Jan/3 DwightKr Created
  10. //
  11. //----------------------------------------------------------------------------
  12. #include <pch.cxx>
  13. #pragma hdrstop
  14. //+---------------------------------------------------------------------------
  15. //
  16. // Function: IsAReplaceableParameter, public
  17. //
  18. // Synopsis: Determines whether parameter replacement needs to be done
  19. // on a string.
  20. //
  21. // Arguments: [wcsString] - string to perform replacement on
  22. //
  23. // Returns: eIsSimpleString - if no replacement needs to be done
  24. // eIsSimpleReplacement - if it's a simple string substitution
  25. // eIsComplexReplacement - it's more complex than simple subst.
  26. //
  27. // History: 96-Apr-04 AlanW Created
  28. //
  29. //----------------------------------------------------------------------------
  30. EIsReplaceable IsAReplaceableParameter( WCHAR const * wcsString )
  31. {
  32. if ( wcsString == 0 || *wcsString == 0 )
  33. return eIsSimpleString;
  34. BOOL fStartWithPercent = *wcsString == L'%';
  35. wcsString++;
  36. while ( *wcsString )
  37. {
  38. if ( *wcsString == L'%' )
  39. {
  40. if ( !fStartWithPercent ||
  41. wcsString[1] != L'\0' )
  42. return eIsComplexReplacement;
  43. else
  44. return eIsSimpleReplacement;
  45. }
  46. if ( fStartWithPercent && iswspace( *wcsString ) )
  47. break;
  48. wcsString++;
  49. }
  50. return fStartWithPercent ? eIsComplexReplacement : eIsSimpleString;
  51. }
  52. //+---------------------------------------------------------------------------
  53. //
  54. // Function: ReplaceNumericParameter, public
  55. //
  56. // Synopsis: Returns the value of a numeric parameter.
  57. //
  58. // Arguments: [wcsVariableString] - string to perform replacement on
  59. // [variableSet] - list of replaceable parameters
  60. // [outputFormat] - format of numbers & dates
  61. // [defaultVal] - default value for result
  62. // [minVal] - minumum value for result
  63. // [maxVal] - maxumum value for result
  64. //
  65. // Returns: ULONG - parameter value
  66. //
  67. // History: 96-Apr-04 AlanW Created
  68. //
  69. //----------------------------------------------------------------------------
  70. ULONG ReplaceNumericParameter( WCHAR const * wcsVariableString,
  71. CVariableSet & variableSet,
  72. COutputFormat & outputFormat,
  73. ULONG defaultVal,
  74. ULONG minVal,
  75. ULONG maxVal )
  76. {
  77. ULONG ulValue = defaultVal;
  78. if ( 0 == wcsVariableString )
  79. ulValue = defaultVal;
  80. else if ( IsAReplaceableParameter( wcsVariableString ) == eIsSimpleString )
  81. ulValue = wcstoul( wcsVariableString, 0, 10 );
  82. else
  83. {
  84. ULONG cchValue;
  85. XPtrST<WCHAR> xStr( ReplaceParameters( wcsVariableString,
  86. variableSet,
  87. outputFormat,
  88. cchValue ) );
  89. if ( cchValue > 0 )
  90. ulValue = wcstoul( xStr.GetPointer(), 0, 10 );
  91. }
  92. ulValue = min( max( minVal, ulValue ), maxVal );
  93. return ulValue;
  94. }
  95. //+---------------------------------------------------------------------------
  96. //
  97. // Function: ReplaceParameters - public
  98. //
  99. // Synopsis: Generates a new string, replacing the replaceable
  100. // parameters with their current values
  101. //
  102. // Arguments: [wcsVariableString] - string to perform replacement on
  103. // [variableSet] - list of replaceable parameters
  104. // [outputFormat] - format of numbers & dates
  105. // [cwcOut] - returns length of returned string
  106. //
  107. // Returns: WCHAR * new string
  108. //
  109. // History: 96-Feb-14 DwightKr Created
  110. // 96-Apr-04 AlanW Added simple string substitution
  111. //
  112. //----------------------------------------------------------------------------
  113. WCHAR * ReplaceParameters( WCHAR const * wcsVariableString,
  114. CVariableSet & variableSet,
  115. COutputFormat & outputFormat,
  116. ULONG & cwcOut )
  117. {
  118. if ( 0 == wcsVariableString )
  119. {
  120. cwcOut = 0;
  121. return 0;
  122. }
  123. switch ( IsAReplaceableParameter( wcsVariableString ) )
  124. {
  125. case eIsSimpleString:
  126. {
  127. ULONG cwcString = wcslen( wcsVariableString ) + 1;
  128. WCHAR * wcsString = new WCHAR[ cwcString ];
  129. RtlCopyMemory( wcsString,
  130. wcsVariableString,
  131. cwcString * sizeof(WCHAR) );
  132. cwcOut = cwcString - 1;
  133. return wcsString;
  134. }
  135. case eIsSimpleReplacement:
  136. {
  137. ULONG cwcString = wcslen ( wcsVariableString );
  138. Win4Assert( wcsVariableString[0] == L'%' &&
  139. wcsVariableString[cwcString-1] == L'%' );
  140. XPtrST<WCHAR> xStr( new WCHAR[ cwcString+1 ] );
  141. RtlCopyMemory( xStr.GetPointer(),
  142. wcsVariableString,
  143. cwcString * sizeof(WCHAR) );
  144. xStr.GetPointer()[ cwcString ] = L'\0';
  145. //
  146. // Null out '%' at end of variable name
  147. //
  148. xStr.GetPointer()[ cwcString-1 ] = L'\0';
  149. _wcsupr( xStr.GetPointer() ); // var. lookup requires upper case
  150. ULONG cwcValue = 0;
  151. WCHAR const * wcsValue =
  152. variableSet.GetStringValueRAW( xStr.GetPointer()+1,
  153. ISAPIVariableNameHash( xStr.GetPointer()+1 ),
  154. outputFormat,
  155. cwcValue );
  156. if ( 0 != wcsValue )
  157. {
  158. if (cwcValue > cwcString )
  159. {
  160. // Realloc string buffer for value replacement
  161. delete xStr.Acquire();
  162. xStr.Set( new WCHAR[ cwcValue+1 ] );
  163. }
  164. RtlCopyMemory( xStr.GetPointer(),
  165. wcsValue,
  166. cwcValue * sizeof(WCHAR) );
  167. xStr.GetPointer()[ cwcValue ] = L'\0';
  168. cwcOut = cwcValue;
  169. }
  170. else
  171. {
  172. //
  173. // Restore '%' at end of variable name
  174. //
  175. xStr.GetPointer()[ cwcString-1 ] = wcsVariableString[ cwcString-1 ];
  176. cwcOut = cwcString;
  177. }
  178. ciGibDebugOut(( DEB_ITRACE, "Adding %ws as a simple replaceable parameter\n",
  179. xStr.GetPointer() ));
  180. return xStr.Acquire();
  181. }
  182. case eIsComplexReplacement:
  183. {
  184. CParameterReplacer varReplacer( wcsVariableString,
  185. L"%",
  186. L"%" );
  187. varReplacer.ParseString( variableSet );
  188. CVirtualString wcsVirtualString;
  189. varReplacer.ReplaceParams( wcsVirtualString,
  190. variableSet,
  191. outputFormat );
  192. ciGibDebugOut(( DEB_ITRACE, "Adding %ws as a complex replaceable parameter\n",
  193. wcsVirtualString.Get() ));
  194. cwcOut = wcsVirtualString.StrLen();
  195. return wcsVirtualString.StrDup();
  196. }
  197. default:
  198. Win4Assert( !"Bad return from IsAReplaceableParameter" );
  199. return 0;
  200. }
  201. }
  202. //
  203. // The path given for the catalog should leave room for \Catalog.Wci\8.3
  204. // Leave room for 2 8.3 names with a backslash.
  205. //
  206. const ULONG MAX_CAT_PATH = MAX_PATH - 13*2;
  207. //+---------------------------------------------------------------------------
  208. //
  209. // Member: IsAValidCatalog
  210. //
  211. // Synopsis: Determines if the catalog specified is valid.
  212. //
  213. // Arguments: [wcsCatalog] - path to catalog or the catalog name
  214. // [cwc] - length of the string
  215. //
  216. // History: 96-Mar-25 DwightKr Created
  217. //
  218. //----------------------------------------------------------------------------
  219. BOOL IsAValidCatalog(
  220. WCHAR const * wcsCatalog,
  221. ULONG cwc )
  222. {
  223. if ( cwc >= MAX_CAT_PATH ||
  224. 0 == cwc )
  225. {
  226. ciGibDebugOut(( DEB_ERROR, "length invalid for catalog (%ws)\n",
  227. wcsCatalog ));
  228. return FALSE;
  229. }
  230. // Can't do additional checking since:
  231. // 1) if the machine is remote, the catalog path is meaningless
  232. // 2) it's probably a catalog name, not a path anyway
  233. return TRUE;
  234. } //IsAValidCatalog
  235. //+---------------------------------------------------------------------------
  236. //
  237. // Function: IDQ_wtol
  238. //
  239. // Synopsis: Super-strict long parser, inspired by Mihai
  240. //
  241. // Arguments: [pwcBuf] - the string containing the long
  242. //
  243. // History: 96-Jun-7 dlee Created
  244. //
  245. //----------------------------------------------------------------------------
  246. LONG IDQ_wtol( WCHAR const * pwcBuf )
  247. {
  248. WCHAR *pwcEnd = (WCHAR *) pwcBuf;
  249. LONG l = wcstol( pwcBuf, &pwcEnd, 10 );
  250. if ( pwcEnd == pwcBuf )
  251. THROW( CException( STATUS_INVALID_PARAMETER ) );
  252. while ( iswspace( *pwcEnd ) )
  253. pwcEnd++;
  254. if ( 0 != *pwcEnd )
  255. THROW( CException( STATUS_INVALID_PARAMETER ) );
  256. return l;
  257. } // IDQ_wtol