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.

402 lines
12 KiB

  1. #include "wudetect.h"
  2. /////////////////////////////////////////////////////////////////////////////
  3. // CExpressionParser::dwKeyType
  4. //
  5. //
  6. // Parameters:
  7. //
  8. // Comments :
  9. /////////////////////////////////////////////////////////////////////////////
  10. /////////////////////////////////////////////////////////////////////////////
  11. //
  12. // Class CExpressionParser
  13. // Function fKeyType
  14. //---------------------------------------------------------------------------
  15. //
  16. // Return Value --- TRUE if key type match made, FALSE if no match made
  17. // Parameter
  18. // TCHAR* szRootType --- [IN] string contains the value of key type
  19. // HKEY* phkey --- [OUT] retrieved key type value
  20. /////////////////////////////////////////////////////////////////////////////
  21. //
  22. // Modified by RogerJ, 03/09/00
  23. // Original Creator Unknown
  24. // Modification --- UNICODE and Win64 ready
  25. //
  26. /////////////////////////////////////////////////////////////////////////////
  27. bool CExpressionParser::fKeyType(TCHAR *szRootType, HKEY *phKey)
  28. {
  29. bool fError = false;
  30. if ( lstrcmpi(HKEY_LOCAL_MACHINE_ROOT, szRootType) == 0 )
  31. {
  32. *phKey = HKEY_LOCAL_MACHINE;
  33. }
  34. else if ( lstrcmpi(HKEY_CURRENT_USER_ROOT, szRootType) == 0 )
  35. {
  36. *phKey = HKEY_CURRENT_USER;
  37. }
  38. else if ( lstrcmpi(HKEY_CLASSES_ROOT_ROOT, szRootType) == 0 )
  39. {
  40. *phKey = HKEY_CLASSES_ROOT;
  41. }
  42. else if ( lstrcmpi(HKEY_CURRENT_CONFIG_ROOT, szRootType) == 0 )
  43. {
  44. *phKey = HKEY_CURRENT_CONFIG;
  45. }
  46. else if ( lstrcmpi(HKEY_USERS_ROOT, szRootType) == 0 )
  47. {
  48. *phKey = HKEY_USERS;
  49. }
  50. else if ( lstrcmpi(HKEY_PERFORMANCE_DATA_ROOT, szRootType) == 0 )
  51. {
  52. *phKey = HKEY_PERFORMANCE_DATA;
  53. }
  54. else if ( lstrcmpi(HKEY_DYN_DATA_ROOT, szRootType) == 0 )
  55. {
  56. *phKey = HKEY_DYN_DATA;
  57. }
  58. else
  59. {
  60. fError = true;
  61. }
  62. return fError;
  63. }
  64. /////////////////////////////////////////////////////////////////////////////
  65. // CExpressionParser::fDetectRegSubStr
  66. // Detect a substring in registry datum.
  67. //
  68. // Form: E=RegSubstr,<SubStr>,<RootKey>,<KeyPath>,<RegValue>,<RegData>
  69. //
  70. // Comments :
  71. /////////////////////////////////////////////////////////////////////////////
  72. /////////////////////////////////////////////////////////////////////////////
  73. // This function is not modifed to be UNICODE ready, since it is not compiled
  74. /////////////////////////////////////////////////////////////////////////////
  75. #if 0
  76. bool CExpressionParser::fDetectRegSubStr(TCHAR * pszBuf)
  77. {
  78. DWORD dwInstallStatus = DET_NOTINSTALLED;
  79. HKEY hKeyRoot;
  80. HKEY hKey;
  81. DWORD type;
  82. char szTargetKeyName[MAX_PATH];
  83. char szTargetKeyValue[MAX_PATH];
  84. char szKeyMissingStatus[MAX_PATH];
  85. char szData[MAX_PATH];
  86. char szSubStr[MAX_PATH];
  87. char szBuf[MAX_PATH];
  88. // get the registry key name from the components section of the
  89. // CIF file.
  90. if ( FGetCifEntry(pDetection, DETREG_KEY, szBuf, sizeof(szBuf)) &&
  91. (dwKeyType(szBuf, &hKeyRoot, szTargetKeyName, sizeof(szTargetKeyName)) == ERROR_SUCCESS) )
  92. {
  93. if ( RegOpenKeyEx( hKeyRoot,
  94. szTargetKeyName,
  95. 0,
  96. KEY_QUERY_VALUE,
  97. &hKey) == ERROR_SUCCESS )
  98. {
  99. if ( FGetCifEntry(pDetection, DETREG_SUBSTR, szBuf, sizeof(szBuf)) &&
  100. (GetStringField2(szBuf, 0, szTargetKeyValue, sizeof(szTargetKeyValue)) != 0) &&
  101. (GetStringField2(szBuf, 1, szKeyMissingStatus, sizeof(szKeyMissingStatus)) != 0) )
  102. {
  103. DWORD size = sizeof(szData);
  104. if ( RegQueryValueEx(hKey,
  105. szTargetKeyValue,
  106. 0,
  107. &type,
  108. (BYTE *)szData,
  109. &size) == ERROR_SUCCESS )
  110. {
  111. if ( type == REG_SZ )
  112. {
  113. _strlwr(szData);
  114. // iterate thru the substrings looking for a match.
  115. int index = 2;
  116. while ( GetStringField2(szBuf, index, szSubStr, sizeof(szSubStr)) != 0 )
  117. {
  118. _strlwr(szSubStr);
  119. if ( strstr(szData, szSubStr) != NULL )
  120. {
  121. *pDetection->pdwInstalledVer = 1;
  122. *pDetection->pdwInstalledBuild = 1;
  123. dwInstallStatus = DET_INSTALLED;
  124. goto quit_while;
  125. }
  126. index++;
  127. }
  128. quit_while:;
  129. }
  130. }
  131. else
  132. {
  133. // if we get an error, assume the key does not exist. Note that if
  134. // the status is DETFIELD_NOT_INSTALLED then we don't have to do
  135. // anything since that is the default status.
  136. if ( lstrcmpi(DETFIELD_INSTALLED, szKeyMissingStatus) == 0 )
  137. {
  138. dwInstallStatus = DET_INSTALLED;
  139. }
  140. }
  141. }
  142. RegCloseKey(hKey);
  143. }
  144. }
  145. cleanup:
  146. return dwInstallStatus;
  147. return false;
  148. }
  149. #endif
  150. /////////////////////////////////////////////////////////////////////////////
  151. // CExpressionParser::fMapComparisonToken
  152. // Detect file version.
  153. //
  154. // Form: _E1=FileVer,sysdir,ntdll.dll,=,4.06.00.0407,4.06.00.0407
  155. //
  156. // Comments :
  157. /////////////////////////////////////////////////////////////////////////////
  158. /////////////////////////////////////////////////////////////////////////////
  159. //
  160. // Class CExpressionParser
  161. // Function fMapComparisonToken
  162. //---------------------------------------------------------------------------
  163. //
  164. // Return Value --- TRUE if a matching is found, FALSE otherwise
  165. // Parameter
  166. // TCHAR* pszComparisonToken --- [IN] the token need to find a match
  167. // enumToken* penToken --- [OUT] token enum value found, if no token found, the value is undetermined
  168. /////////////////////////////////////////////////////////////////////////////
  169. //
  170. // Modified by RogerJ, 03/09/00
  171. // Original Creator Unkown
  172. // Modification --- UNICODE and Win64 ready
  173. //
  174. /////////////////////////////////////////////////////////////////////////////
  175. bool CExpressionParser::fMapComparisonToken(TCHAR *pszComparisonToken,
  176. enumToken *penToken)
  177. {
  178. static TokenMapping grComparisonTokenMap[] =
  179. {
  180. {TEXT("="), COMP_EQUALS},
  181. {TEXT("!="), COMP_NOT_EQUALS},
  182. {TEXT("<"), COMP_LESS_THAN},
  183. {TEXT("<="), COMP_LESS_THAN_EQUALS},
  184. {TEXT(">"), COMP_GREATER_THAN},
  185. {TEXT(">="), COMP_GREATER_THAN_EQUALS}
  186. };
  187. return fMapToken(pszComparisonToken,
  188. sizeof(grComparisonTokenMap)/sizeof(grComparisonTokenMap[0]),
  189. grComparisonTokenMap,
  190. penToken);
  191. }
  192. /////////////////////////////////////////////////////////////////////////////
  193. // CExpressionParser::fMapRootDirToken
  194. // Detect file version.
  195. //
  196. // Form: _E1=FileVer,sysdir,ntdll.dll,=,4.06.00.0407,4.06.00.0407
  197. //
  198. // Comments :
  199. /////////////////////////////////////////////////////////////////////////////
  200. /////////////////////////////////////////////////////////////////////////////
  201. //
  202. // Class CExpressionParser
  203. // Function fMapRootDirToken
  204. //---------------------------------------------------------------------------
  205. //
  206. // Return Value --- TRUE if a matching is found, FALSE otherwise
  207. // Parameter
  208. // TCHAR* pszRootDirToken --- [IN] the token need to find a match
  209. // enumToken* penToken --- [OUT] token enum value found, if no token found, the value is undetermined
  210. /////////////////////////////////////////////////////////////////////////////
  211. //
  212. // Modified by RogerJ, 03/09/00
  213. // Original Creator Unkown
  214. // Modification --- UNICODE and Win64 ready
  215. //
  216. /////////////////////////////////////////////////////////////////////////////
  217. bool CExpressionParser::fMapRootDirToken(TCHAR *pszRootDirToken, enumToken *penToken)
  218. {
  219. static TokenMapping grDirectoryTokenMap[] =
  220. {
  221. {TEXT("sysdir"), DIR_SYSTEM},
  222. {TEXT("windir"), DIR_WINDOWS},
  223. };
  224. return fMapToken(pszRootDirToken,
  225. sizeof(grDirectoryTokenMap)/sizeof(grDirectoryTokenMap[0]),
  226. grDirectoryTokenMap,
  227. penToken);
  228. }
  229. /////////////////////////////////////////////////////////////////////////////
  230. // CExpressionParser::fMapToken
  231. // Detect file version.
  232. //
  233. // Form: _E1=FileVer,sysdir,ntdll.dll,=,4.06.00.0407,4.06.00.0407
  234. //
  235. // Comments :
  236. /////////////////////////////////////////////////////////////////////////////
  237. /////////////////////////////////////////////////////////////////////////////
  238. //
  239. // Class CExpressionParser
  240. // Function fMapToken
  241. //---------------------------------------------------------------------------
  242. //
  243. // Return Value --- TRUE if a matching is found, FALSE otherwise
  244. // Parameter
  245. // TCHAR* pszToken --- [IN] the token need to find a match
  246. // int nSize --- [IN] number of tokens to be matched as the template
  247. // TokenMapping grTokenMap[] --- [IN] token template to be matched
  248. // enumToken* penToken --- [OUT] token enum value found, if no token found, the value is undetermined
  249. /////////////////////////////////////////////////////////////////////////////
  250. //
  251. // Modified by RogerJ, 03/09/00
  252. // Original Creator Unkown
  253. // Modification --- UNICODE and Win64 ready
  254. //
  255. /////////////////////////////////////////////////////////////////////////////
  256. bool CExpressionParser::fMapToken(TCHAR *pszToken,
  257. int nSize,
  258. TokenMapping grTokenMap[],
  259. enumToken *penToken)
  260. {
  261. for ( int index = 0; index < nSize; index++ )
  262. {
  263. if ( _tcscmp(pszToken, grTokenMap[index].pszToken) == 0 )
  264. {
  265. *penToken = grTokenMap[index].enToken;
  266. return true;
  267. }
  268. }
  269. return false;
  270. }
  271. /////////////////////////////////////////////////////////////////////////////
  272. // CExpressionParser::fDetectFileVer
  273. // Detect file version.
  274. //
  275. // Form: _E1=FileVer,sysdir,ntdll.dll,=,4.06.00.0407,4.06.00.0407
  276. //
  277. // Comments :
  278. /////////////////////////////////////////////////////////////////////////////
  279. /////////////////////////////////////////////////////////////////////////////
  280. //
  281. // Class CExpressionParser
  282. // Function fDetectFileVer
  283. //---------------------------------------------------------------------------
  284. //
  285. // Return Value --- TRUE if version of input files matched the file version in the system, FALSE otherwise
  286. // Parameter
  287. // TCHAR* pszBuf --- [IN] the name of the input file
  288. //////////////////////////////////////////////////////////////////////////////
  289. //
  290. // Modified by RogerJ, 03/09/00
  291. // Original Creator Unkown
  292. // Modification --- UNICODE and Win64 ready
  293. //
  294. /////////////////////////////////////////////////////////////////////////////
  295. const DWORD WU_MAX_COMPARISON_LEN = 3;
  296. const DWORD WU_MAX_VERSION_LEN = 30;
  297. bool CExpressionParser::fDetectFileVer(TCHAR * pszBuf)
  298. {
  299. bool fResult = false;
  300. TCHAR szRootDir[MAX_PATH];
  301. TCHAR szFile[MAX_PATH];
  302. TCHAR szFilePath[MAX_PATH];
  303. TCHAR szComparison[WU_MAX_COMPARISON_LEN];
  304. TCHAR szVersion[WU_MAX_VERSION_LEN];
  305. enumToken enComparisonToken;
  306. enumToken enRootDirToken;
  307. // Get reg root type (HKLM, etc)
  308. if ( (GetStringField2(pszBuf, 1, szRootDir, sizeof(szRootDir)/sizeof(TCHAR)) != 0) &&
  309. (GetStringField2(pszBuf, 2, szFile, sizeof(szFile)/sizeof(TCHAR)) != 0) &&
  310. fMapRootDirToken(szRootDir, &enRootDirToken) )
  311. {
  312. // create the file path
  313. if ( enRootDirToken == DIR_SYSTEM )
  314. {
  315. if ( GetSystemDirectory(szFilePath, sizeof(szFilePath)/sizeof(TCHAR)) == 0 )
  316. return false;
  317. }
  318. else // DIR_WINDOWS
  319. {
  320. if ( GetWindowsDirectory(szFilePath, sizeof(szFilePath)/sizeof(TCHAR)) == 0 )
  321. return false;
  322. }
  323. if (szFilePath[_tcslen(szFilePath)-1]!='\\') _tcscat(szFilePath, TEXT("\\"));
  324. _tcscat(szFilePath, szFile);
  325. if ( (GetStringField2(pszBuf, 3, szComparison, sizeof(szComparison)/sizeof(TCHAR)) != 0) &&
  326. fMapComparisonToken(szComparison, &enComparisonToken) )
  327. {
  328. DWORD dwSize;
  329. DWORD dwReserved;
  330. DWORD dwVer, dwBuild;
  331. VS_FIXEDFILEINFO *pVerInfo;
  332. UINT uLen;
  333. dwSize = GetFileVersionInfoSize(szFilePath, &dwReserved);
  334. if ( dwSize > 0)
  335. {
  336. TCHAR *pbVerInfo = (TCHAR *)malloc(dwSize);
  337. if ( GetFileVersionInfo(szFilePath, dwReserved, dwSize, pbVerInfo) &&
  338. (VerQueryValue(pbVerInfo, TEXT("\\"), (void **)&pVerInfo, &uLen) != 0) )
  339. {
  340. for ( int index = 4;
  341. !fResult && (GetStringField2(pszBuf, index, szVersion, sizeof(szVersion)/sizeof(TCHAR)) != 0);
  342. index++ )
  343. {
  344. fConvertDotVersionStrToDwords(szVersion, &dwVer, &dwBuild);
  345. fResult = fCompareVersion(pVerInfo->dwProductVersionMS,
  346. pVerInfo->dwProductVersionLS,
  347. enComparisonToken,
  348. dwVer,
  349. dwBuild);
  350. }
  351. }
  352. free(pbVerInfo);
  353. }
  354. }
  355. else
  356. // just a file existence check.
  357. fResult = (_taccess(szFilePath, 00) != -1);
  358. }
  359. return fResult;
  360. }