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.

429 lines
13 KiB

  1. //#include <nt.h>
  2. //#include <ntrtl.h>
  3. //#include <nturtl.h>
  4. //#include <windows.h>
  5. //#include <objbase.h>
  6. //#include <inseng.h>
  7. //#include "utils2.h"
  8. #include "wudetect.h"
  9. /////////////////////////////////////////////////////////////////////////////
  10. // dwParseValue
  11. //
  12. // Parses out the registry key name, value, and type that needs to
  13. // be opened to determine the installation status of the component.
  14. /////////////////////////////////////////////////////////////////////////////
  15. //
  16. // Class CExpressionParser
  17. // Function dwParseValue
  18. //---------------------------------------------------------------------------
  19. //
  20. // Return Value --- DWORD, if the function succeeded, return ERROR_SUCCESS
  21. // if the function failed, return ERROR_BADKEY
  22. // Parameters
  23. // DWORD iToken --- [IN] Index Number of Field to looking for
  24. // TCHAR* szBuf --- [IN] String to search for
  25. // TargetRegValue& targerValue --- [OUT] two (three) fields will be set if function succeeded,
  26. // szName field will be set to the Name in the String token
  27. // szType field will be set to either REG_DWORD, REG_SZ_TYPE or REG_BINARY_TYPE depends on the String Token
  28. // if szType is REG_DWORD, the dw field will be set to the value depends on the String
  29. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  30. //
  31. // Modified by RogerJ, 03/08/00
  32. // Original Creator Unknown
  33. // Modification --- UNICODE and Win64 ready
  34. //
  35. //////////////////////////////////////////////////////////////////////////////////////////////////
  36. DWORD CExpressionParser::dwParseValue(DWORD iToken, TCHAR * szBuf, TargetRegValue & targetValue)
  37. {
  38. DWORD dwStatus = ERROR_BADKEY;
  39. TCHAR szType[MAX_PATH]; // BUGBUG - get real value
  40. TCHAR szValue[MAX_PATH]; // BUGBUG - get real value
  41. // get the data type
  42. if ( (GetStringField2(szBuf, iToken, targetValue.szName, sizeof(targetValue.szName)/sizeof(TCHAR)) != 0) &&
  43. (GetStringField2(szBuf, ++iToken, szType, sizeof(szType)/sizeof(TCHAR)) != 0) )
  44. {
  45. if ( lstrcmpi(REG_NONE_TYPE, szType) == 0 )
  46. {
  47. targetValue.type = REG_NONE;
  48. dwStatus = ERROR_SUCCESS;
  49. }
  50. else
  51. {
  52. if ( GetStringField2(szBuf, ++iToken, szValue, sizeof(szValue)/sizeof(TCHAR)) != 0 )
  53. {
  54. if ( lstrcmpi(REG_DWORD_TYPE, szType) == 0 )
  55. {
  56. targetValue.type = REG_DWORD;
  57. targetValue.dw = _ttol(szValue);
  58. dwStatus = ERROR_SUCCESS;
  59. }
  60. else if ( lstrcmpi(REG_SZ_TYPE, szType) == 0 )
  61. {
  62. targetValue.type = REG_SZ;
  63. lstrcpy(targetValue.sz, szValue);
  64. dwStatus = ERROR_SUCCESS;
  65. }
  66. else if ( lstrcmpi(REG_BINARY_TYPE, szType) == 0 )
  67. {
  68. targetValue.type = REG_BINARY;
  69. lstrcpy(targetValue.sz, szValue);
  70. dwStatus = ERROR_SUCCESS;
  71. }
  72. }
  73. }
  74. }
  75. return dwStatus;
  76. }
  77. /////////////////////////////////////////////////////////////////////////////
  78. // fCompareVersion
  79. /////////////////////////////////////////////////////////////////////////////
  80. //
  81. // Class CExpressionParser
  82. // Function fCompareVersion
  83. //--------------------------------------------------------------------------
  84. // Return Value --- TRUE if value equals, FALSE if value does not equal or
  85. // no Comparison type specified exist
  86. // Parameter
  87. // DWORD dwVer1 --- [IN] version number of first value
  88. // DWORD dwBuild1 --- [IN] build number of first value
  89. // enumToken enComparisonToken --- [IN] reason to compare
  90. // DWORD dwVer2 --- [IN] version number of second value
  91. // DWORD dwBuild2 --- [IN] build number of second value
  92. /////////////////////////////////////////////////////////////////////////////
  93. //
  94. // Original Creator Unknown
  95. // No modification made at 03/08/00 by RogerJ
  96. //
  97. ////////////////////////////////////////////////////////////////////////////
  98. bool CExpressionParser::fCompareVersion(IN DWORD dwVer1,
  99. IN DWORD dwBuild1,
  100. IN enumToken enComparisonToken,
  101. IN DWORD dwVer2,
  102. IN DWORD dwBuild2)
  103. {
  104. bool fResult = false;
  105. switch ( enComparisonToken )
  106. {
  107. case COMP_EQUALS:
  108. fResult = (dwVer1 == dwVer2) && (dwBuild1 == dwBuild2);
  109. break;
  110. case COMP_NOT_EQUALS:
  111. fResult = (dwVer1 != dwVer2) || (dwBuild1 != dwBuild2);
  112. break;
  113. case COMP_LESS_THAN:
  114. fResult = (dwVer1 < dwVer2) || ((dwVer1 == dwVer2) && (dwBuild1 < dwBuild2));
  115. break;
  116. case COMP_LESS_THAN_EQUALS:
  117. fResult = (dwVer1 < dwVer2) || ((dwVer1 == dwVer2) && (dwBuild1 <= dwBuild2));
  118. break;
  119. case COMP_GREATER_THAN:
  120. fResult = (dwVer1 > dwVer2) || ((dwVer1 == dwVer2) && (dwBuild1 > dwBuild2));
  121. break;
  122. case COMP_GREATER_THAN_EQUALS:
  123. fResult = (dwVer1 > dwVer2) || ((dwVer1 == dwVer2) && (dwBuild1 >= dwBuild2));
  124. break;
  125. }
  126. return fResult;
  127. }
  128. /////////////////////////////////////////////////////////////////////////////
  129. // fMapRegRoot
  130. // Determines the registry root (HKLM, HKCU, etc) that the key lies under.
  131. /////////////////////////////////////////////////////////////////////////////
  132. //
  133. // Function fMapRegRoot
  134. //---------------------------------------------------------------------------
  135. //
  136. // Return Value --- TRUE if function succeeded, FALSE if can't find correct registry root
  137. // Parameter
  138. // TCHAR* pszBuf --- [IN] String to search for
  139. // DWORD index --- [IN] Index Number of Field to looking for
  140. // HKEY* phKey --- [OUT] key value found
  141. /////////////////////////////////////////////////////////////////////////////
  142. //
  143. // Modified by RogerJ, 03/08/00
  144. // Original Creator Unkown
  145. // Modification made --- UNICODE and Win64 Ready
  146. //
  147. /////////////////////////////////////////////////////////////////////////////
  148. bool fMapRegRoot(TCHAR *pszBuf, DWORD index, HKEY *phKey)
  149. {
  150. TCHAR szRootType[MAX_PATH];
  151. if ( GetStringField2(pszBuf, (UINT)index, szRootType, sizeof(szRootType)/sizeof(TCHAR)) == 0 )
  152. return false;
  153. if ( lstrcmpi(HKEY_LOCAL_MACHINE_ROOT, szRootType) == 0 )
  154. {
  155. *phKey = HKEY_LOCAL_MACHINE;
  156. }
  157. else if ( lstrcmpi(HKEY_CURRENT_USER_ROOT, szRootType) == 0 )
  158. {
  159. *phKey = HKEY_CURRENT_USER;
  160. }
  161. else if ( lstrcmpi(HKEY_CLASSES_ROOT_ROOT, szRootType) == 0 )
  162. {
  163. *phKey = HKEY_CLASSES_ROOT;
  164. }
  165. else if ( lstrcmpi(HKEY_CURRENT_CONFIG_ROOT, szRootType) == 0 )
  166. {
  167. *phKey = HKEY_CURRENT_CONFIG;
  168. }
  169. else if ( lstrcmpi(HKEY_USERS_ROOT, szRootType) == 0 )
  170. {
  171. *phKey = HKEY_USERS;
  172. }
  173. else if ( lstrcmpi(HKEY_PERFORMANCE_DATA_ROOT, szRootType) == 0 )
  174. {
  175. *phKey = HKEY_PERFORMANCE_DATA;
  176. }
  177. else if ( lstrcmpi(HKEY_DYN_DATA_ROOT, szRootType) == 0 )
  178. {
  179. *phKey = HKEY_DYN_DATA;
  180. }
  181. else return false;
  182. return true;
  183. }
  184. //--------------------------------------------------------------------------
  185. // GetStringField2
  186. //--------------------------------------------------------------------------
  187. //
  188. // Function GetStringField2
  189. //--------------------------------------------------------------------------
  190. //
  191. // Return Value: DWORD, the number of TCHAR copied, not including the NULL character
  192. // Parameters:
  193. // LPTSTR szStr --- [IN] String to search for
  194. // UINT uField --- [IN] Index Number of Field to looking for
  195. // LPTSTR szBuf --- [IN,OUT] String buffer to copy to
  196. // UINT cBufSize --- [IN] Size of szBuf in TCHAR
  197. //////////////////////////////////////////////////////////////////////////////
  198. //
  199. // Modified by RogerJ, 03/08/00
  200. // Original Creator Unknown
  201. // Modification made --- UNICODE and Win64 Compatbility
  202. //
  203. //////////////////////////////////////////////////////////////////////////////
  204. #define WHITESPACE TEXT(" \t")
  205. DWORD GetStringField2(LPTSTR szStr, UINT uField, LPTSTR szBuf, UINT cBufSize)
  206. {
  207. LPTSTR pszBegin = szStr;
  208. LPTSTR pszEnd;
  209. UINT i;
  210. DWORD dwToCopy;
  211. if ( (cBufSize == 0) || (szStr == NULL) || (szBuf == NULL) )
  212. {
  213. return 0;
  214. }
  215. szBuf[0] = '\0';
  216. // look for fields based on commas but handle quotes.
  217. // check the ith Field, each field separated by either quote or comma
  218. for (i = 0 ;i < uField; i++ )
  219. {
  220. // skip spaces
  221. pszBegin += _tcsspn(pszBegin, WHITESPACE);
  222. // handle quotes
  223. if ( *pszBegin == '"' )
  224. {
  225. pszBegin = _tcschr(++pszBegin, '"');
  226. if ( pszBegin == NULL )
  227. {
  228. return 0; // invalid string
  229. }
  230. pszBegin++; // skip trailing quote
  231. // find start of next string
  232. pszBegin += _tcsspn(pszBegin, WHITESPACE);
  233. if ( *pszBegin != ',' )
  234. {
  235. return 0;
  236. }
  237. }
  238. else
  239. {
  240. pszBegin = _tcschr(++pszBegin, ',');
  241. if ( pszBegin == NULL )
  242. {
  243. return 0; // field isn't here
  244. }
  245. }
  246. pszBegin++;
  247. }
  248. // pszBegin points to the start of the desired string.
  249. // skip spaces
  250. pszBegin += _tcsspn(pszBegin, WHITESPACE);
  251. // handle quotes
  252. if ( *pszBegin == '"' )
  253. {
  254. pszEnd = _tcschr(++pszBegin, '"');
  255. if ( pszEnd == NULL )
  256. {
  257. return 0; // invalid string
  258. }
  259. }
  260. else
  261. {
  262. pszEnd = pszBegin + 1 + _tcscspn(pszBegin + 1, TEXT(","));
  263. while ( (pszEnd > pszBegin) &&
  264. ((*(pszEnd - 1) == ' ') || (*(pszEnd - 1) == '\t')) )
  265. {
  266. pszEnd--;
  267. }
  268. }
  269. // length of buffer to copy should never exceed 32 bits.
  270. dwToCopy = (DWORD)(pszEnd - pszBegin + 1);
  271. if ( dwToCopy > cBufSize )
  272. {
  273. dwToCopy = cBufSize;
  274. }
  275. lstrcpyn(szBuf, pszBegin, dwToCopy);
  276. return dwToCopy - 1;
  277. }
  278. //--------------------------------------------------------------------------
  279. // GetIntField
  280. //--------------------------------------------------------------------------
  281. //
  282. // Function GetIntField
  283. //--------------------------------------------------------------------------
  284. //
  285. // Return Value: DWORD, Integer value of wanted field
  286. // Parameters:
  287. // LPTSTR szStr --- [IN] String to search for
  288. // UINT uField --- [IN] Index Number of Field to looking for
  289. // DWORD dwDefault --- [IN] default value
  290. ////////////////////////////////////////////////////////////////////////////
  291. //
  292. // Modified by RogerJ, 03/08/00
  293. // Original Creator Unknown
  294. // Modification made --- UNICODE and Win64 compatibility
  295. // NOTE --- NOT used in current version
  296. //
  297. ////////////////////////////////////////////////////////////////////////////
  298. #if 0 // not used yet
  299. DWORD GetIntField(LPTSTR szStr, UINT uField, DWORD dwDefault)
  300. {
  301. TCHAR szNumBuf[16];
  302. if(GetStringField(szStr, uField, szNumBuf, sizeof(szNumBuf)/sizeof(TCHAR)) == 0)
  303. return dwDefault;
  304. else
  305. return _ttol(szNumBuf);
  306. }
  307. #endif
  308. //--------------------------------------------------------------------------
  309. // ConvertVersionStrToDwords
  310. //--------------------------------------------------------------------------
  311. //
  312. // Function ConvertVersionStrToDwords
  313. //--------------------------------------------------------------------------
  314. //
  315. // Return Value --- no return value
  316. // Parameter
  317. // LPTSTR pszVer --- [IN] input string containing the version and build information
  318. // LPDWORD pdwVer --- [OUT] the version value extracted from pszVer
  319. // LPDWORD pdwBuild --- [OUT] the build value extracted from pszVer
  320. ////////////////////////////////////////////////////////////////////////////
  321. //
  322. // Modified by RogerJ, 03/08/00
  323. // Original Creator Unknown
  324. // Modification --- UNICODE and Win64 ready
  325. // NOTE --- NOT used in current version
  326. //
  327. ////////////////////////////////////////////////////////////////////////////
  328. #if 0 // not used yet
  329. void ConvertVersionStrToDwords(LPTSTR pszVer, LPDWORD pdwVer, LPDWORD pdwBuild)
  330. {
  331. DWORD dwTemp1,dwTemp2;
  332. dwTemp1 = GetIntField(pszVer, 0, 0);
  333. dwTemp2 = GetIntField(pszVer, 1, 0);
  334. *pdwVer = (dwTemp1 << 16) + dwTemp2;
  335. dwTemp1 = GetIntField(pszVer, 2, 0);
  336. dwTemp2 = GetIntField(pszVer, 3, 0);
  337. *pdwBuild = (dwTemp1 << 16) + dwTemp2;
  338. }
  339. #endif
  340. //--------------------------------------------------------------------------
  341. // ConvertDotVersionStrToDwords
  342. //--------------------------------------------------------------------------
  343. //
  344. // Function fConvertDotVersionStrToDwords
  345. //--------------------------------------------------------------------------
  346. //
  347. // Return Value --- always true
  348. // Parameter
  349. // LPTSTR pszVer --- [IN] input version string, should have the format
  350. // of x.x.x.x
  351. // LPDWORD pdwVer --- [OUT] version number extracted from pszVer
  352. // LPDWORD pdwBuild --- [OUT] build number extracted from pszVer
  353. //
  354. ////////////////////////////////////////////////////////////////////////////
  355. //
  356. // Modified by RogerJ, 03/08/00
  357. // Original Creator Unknown
  358. // Modification --- UNICODE and Win64 ready
  359. //
  360. ////////////////////////////////////////////////////////////////////////////
  361. bool fConvertDotVersionStrToDwords(LPTSTR pszVer, LPDWORD pdwVer, LPDWORD pdwBuild)
  362. {
  363. DWORD grVerFields[4] = {0,0,0,0};
  364. TCHAR *pch = pszVer;
  365. grVerFields[0] = _ttol(pch);
  366. for ( int index = 1; index < 4; index++ )
  367. {
  368. while ( IsDigit(*pch) && (*pch != '\0') )
  369. pch++;
  370. if ( *pch == '\0' )
  371. break;
  372. pch++;
  373. grVerFields[index] = _ttol(pch);
  374. }
  375. *pdwVer = (grVerFields[0] << 16) + grVerFields[1];
  376. *pdwBuild = (grVerFields[2] << 16) + grVerFields[3];
  377. return true;
  378. }