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.

713 lines
20 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // WUDetect.cpp
  3. //
  4. // Copyright (C) Microsoft Corp. 1998
  5. // All rights reserved
  6. //
  7. /////////////////////////////////////////////////////////////////////////////
  8. //
  9. // Description:
  10. // DLL loaded by the install engine that exposes entry points
  11. // that can determines the installation status of legacy or complex
  12. // components. The dll name and entry points are specified for a
  13. // component in the CIF file.
  14. /////////////////////////////////////////////////////////////////////////////
  15. #include "wudetect.h"
  16. //#include <stdio.h>
  17. //#include <tTCHAR.h>
  18. //#include <nt.h>
  19. //#include <ntrtl.h>
  20. //#include <nturtl.h>
  21. //#include <windows.h>
  22. //#include <objbase.h>
  23. //#include <inseng.h>
  24. //#include <detdlls.h>
  25. //#include <utils2.h>
  26. /////////////////////////////////////////////////////////////////////////////
  27. // dwKeyType
  28. // Determines the registry root (HKLM, HKCU, etc) that the key lies under.
  29. //
  30. // Parameters:
  31. //
  32. // Comments :
  33. /////////////////////////////////////////////////////////////////////////////
  34. inline DWORD dwKeyType(TCHAR *szBuf, HKEY *phKey, TCHAR * szKeyName, DWORD dwSize)
  35. {
  36. DWORD dwStatus = ERROR_SUCCESS;
  37. TCHAR szRootType[MAX_PATH];
  38. if ( (GetStringField2(szBuf, 0, szRootType, sizeof(szRootType)/sizeof(TCHAR)) == 0) ||
  39. (GetStringField2(szBuf, 1, szKeyName, dwSize) == 0) )
  40. {
  41. dwStatus = ERROR_BADKEY;
  42. }
  43. else if ( lstrcmpi(HKEY_LOCAL_MACHINE_ROOT, szRootType) == 0 )
  44. {
  45. *phKey = HKEY_LOCAL_MACHINE;
  46. }
  47. else if ( lstrcmpi(HKEY_CURRENT_USER_ROOT, szRootType) == 0 )
  48. {
  49. *phKey = HKEY_CURRENT_USER;
  50. }
  51. else if ( lstrcmpi(HKEY_CLASSES_ROOT_ROOT, szRootType) == 0 )
  52. {
  53. *phKey = HKEY_CLASSES_ROOT;
  54. }
  55. else if ( lstrcmpi(HKEY_CURRENT_CONFIG_ROOT, szRootType) == 0 )
  56. {
  57. *phKey = HKEY_CURRENT_CONFIG;
  58. }
  59. else if ( lstrcmpi(HKEY_USERS_ROOT, szRootType) == 0 )
  60. {
  61. *phKey = HKEY_USERS;
  62. }
  63. else if ( lstrcmpi(HKEY_PERFORMANCE_DATA_ROOT, szRootType) == 0 )
  64. {
  65. *phKey = HKEY_PERFORMANCE_DATA;
  66. }
  67. else if ( lstrcmpi(HKEY_DYN_DATA_ROOT, szRootType) == 0 )
  68. {
  69. *phKey = HKEY_DYN_DATA;
  70. }
  71. else
  72. {
  73. dwStatus = ERROR_BADKEY;
  74. }
  75. return dwStatus;
  76. }
  77. /////////////////////////////////////////////////////////////////////////////
  78. // dwParseValue
  79. //
  80. // Parses out the registry key name, value, and type that needs to
  81. // be opened to determine the installation status of the component.
  82. /////////////////////////////////////////////////////////////////////////////
  83. inline DWORD dwParseValue(TCHAR * szBuf, TargetRegValue & targetValue)
  84. {
  85. DWORD dwStatus = ERROR_BADKEY;
  86. TCHAR szType[MAX_PATH]; // BUGBUG - get real value
  87. TCHAR szValue[MAX_PATH]; // BUGBUG - get real value
  88. // get the data type
  89. if ( (GetStringField2(szBuf, 0, targetValue.szName, sizeof(targetValue.szName)/sizeof(TCHAR)) != 0) &&
  90. (GetStringField2(szBuf, 1, szType, sizeof(szType)/sizeof(TCHAR)) != 0) )
  91. {
  92. if ( lstrcmpi(REG_NONE_TYPE, szType) == 0 )
  93. {
  94. targetValue.type = REG_NONE;
  95. dwStatus = ERROR_SUCCESS;
  96. }
  97. else
  98. {
  99. if ( GetStringField2(szBuf, 2, szValue, sizeof(szValue)/sizeof(TCHAR)) != 0 )
  100. {
  101. if ( lstrcmpi(REG_DWORD_TYPE, szType) == 0 )
  102. {
  103. targetValue.type = REG_DWORD;
  104. targetValue.dw = _ttol(szValue);
  105. dwStatus = ERROR_SUCCESS;
  106. }
  107. else if ( lstrcmpi(REG_SZ_TYPE, szType) == 0 )
  108. {
  109. targetValue.type = REG_SZ;
  110. lstrcpy(targetValue.sz, szValue);
  111. dwStatus = ERROR_SUCCESS;
  112. }
  113. }
  114. }
  115. }
  116. return dwStatus;
  117. }
  118. /////////////////////////////////////////////////////////////////////////////
  119. // fCompareVersion
  120. //
  121. // Returns: 1,0,-1 depending on whether dwVersion1 is greater than, equal, or
  122. // less than dwVersion2.
  123. /////////////////////////////////////////////////////////////////////////////
  124. inline int nCompareVersion(IN DWORD dwVer1,
  125. IN DWORD dwBuild1,
  126. IN DWORD dwVer2,
  127. IN DWORD dwBuild2)
  128. {
  129. int nResult = 0;
  130. if ( dwVer1 > dwVer2 )
  131. {
  132. nResult = 1;
  133. }
  134. else if ( dwVer1 < dwVer2 )
  135. {
  136. nResult = -1;
  137. }
  138. else if ( dwBuild1 > dwBuild2 ) // dwVer1 == dwVer2
  139. {
  140. nResult = 1;
  141. }
  142. else if ( dwBuild1 < dwBuild2 ) // dwVer1 == dwVer2
  143. {
  144. nResult = -1;
  145. }
  146. return nResult;
  147. }
  148. /////////////////////////////////////////////////////////////////////////////
  149. // GetCifEntry
  150. // Get an entry from the CIF file.
  151. //
  152. // Comments :
  153. // We get the value differently depending on whether we are being
  154. // called by IE 4 or IE 5 Active Setup.
  155. /////////////////////////////////////////////////////////////////////////////
  156. /////////////////////////////////////////////////////////////////////////////
  157. //
  158. // Function FGetCifEntry
  159. //---------------------------------------------------------------------------
  160. //
  161. // Return Value --- TRUE if Successfully retrieved CIF file value
  162. // FALSE if failed
  163. // Parameter
  164. // TCHAR* pszParamName --- [IN] Name of the CIF file
  165. // TCHAR* pszParamValue --- [OUT] Value of the CIF file
  166. // DWORD cbParamValue --- size of the pszParamValue in TCHAR
  167. // NOTE: This function calls GetCustomData to retrieve the value of CIF file
  168. // GetCustomData is defined in inseng.h which takes only ANSI strings.
  169. // Thus, UNICODE version of this function needed to convert parameters
  170. // to and from ANSI compatibles.
  171. // NOTE: This is a global function. Don't mixed with member function of
  172. // CExpressionParser::fGetCifEntry
  173. //
  174. /////////////////////////////////////////////////////////////////////////////
  175. //
  176. // Modified by RogerJ, 03/09/00
  177. // Original Creator Unknown (YanL?)
  178. // Modification --- UNICODE and Win64 enabled
  179. //
  180. /////////////////////////////////////////////////////////////////////////////
  181. inline bool FGetCifEntry(DETECTION_STRUCT* pDetection,
  182. TCHAR *pszParamName,
  183. TCHAR *pszParamValue,
  184. DWORD cbParamValue)
  185. // pszParamName is [IN], pszParamValue is [OUT], the function GetCustomData requires
  186. // LPSTR for both parameters, string conversion is necessary in the UNICODE case
  187. {
  188. #ifdef UNICODE
  189. bool fSucceed;
  190. char pszParamNameANSI[MAX_PATH];
  191. char pszParamValueANSI[MAX_PATH];
  192. // do UNICODE to ANSI string conversion
  193. // only pszParamName [IN] parameter need to be converted
  194. // wcstombs and mbstowcs do not ensure the last character is NULL
  195. // ensure manually
  196. wcstombs(pszParamNameANSI,pszParamName,MAX_PATH-1);
  197. pszParamNameANSI[MAX_PATH-1]=NULL;
  198. // make actual function call
  199. fSucceed= (ERROR_SUCCESS == pDetection->pCifComp->GetCustomData(pszParamNameANSI,
  200. pszParamValueANSI,
  201. cbParamValue));
  202. // do ANSI to UNICODE string conversion
  203. // only pszParamValue [OUT] parameter need to be converted
  204. mbstowcs(pszParamValue,pszParamValueANSI,cbParamValue-1);
  205. pszParamValue[cbParamValue-1]=(TCHAR)NULL;
  206. return fSucceed;
  207. #else
  208. return (ERROR_SUCCESS == pDetection->pCifComp->GetCustomData(pszParamName,
  209. pszParamValue,
  210. cbParamValue));
  211. #endif
  212. }
  213. /////////////////////////////////////////////////////////////////////////////
  214. // RegKeyExists (EXPORT)
  215. // This API will determine if an application exists based on the
  216. // existence of a registry key and perhaps a value.
  217. //
  218. // Parameters:
  219. //
  220. // Comments :
  221. /////////////////////////////////////////////////////////////////////////////
  222. DWORD WINAPI RegKeyExists(DETECTION_STRUCT *pDetection)
  223. {
  224. DWORD dwInstallStatus = DET_NOTINSTALLED;
  225. HKEY hKeyRoot;
  226. HKEY hKey;
  227. DWORD type;
  228. TCHAR szTargetKeyName[MAX_PATH];
  229. TCHAR szTargetKeyValue[MAX_PATH];
  230. TCHAR szBuf[MAX_PATH];
  231. DWORD dwStatus;
  232. //DWORD dwLen;
  233. // make sure the struct is of the expected size
  234. if ( (pDetection->dwSize >= sizeof(DETECTION_STRUCT)) )
  235. {
  236. // get the registry key name from the components section of the
  237. // CIF file.
  238. if ( FGetCifEntry(pDetection, DETREG_KEY, szBuf, sizeof(szBuf)/sizeof(TCHAR)) )
  239. {
  240. if ( (dwStatus = dwKeyType(szBuf, &hKeyRoot, szTargetKeyName, sizeof(szTargetKeyName)/sizeof(TCHAR))) == ERROR_SUCCESS )
  241. {
  242. // determine if we should log transmissions
  243. if ( RegOpenKeyEx( hKeyRoot,
  244. szTargetKeyName,
  245. 0,
  246. KEY_QUERY_VALUE,
  247. &hKey) == ERROR_SUCCESS )
  248. {
  249. if ( FGetCifEntry(pDetection, DETREG_VALUE, szTargetKeyValue, sizeof(szTargetKeyValue)/sizeof(TCHAR)) )
  250. {
  251. TargetRegValue targetValue;
  252. dwStatus = dwParseValue(szTargetKeyValue, targetValue);
  253. if ( dwStatus == ERROR_SUCCESS )
  254. {
  255. ActualKeyValue keyvalue;
  256. DWORD size = sizeof(keyvalue);
  257. if ( RegQueryValueEx(hKey,
  258. targetValue.szName,
  259. 0,
  260. &type,
  261. (BYTE *)&keyvalue,
  262. &size) == ERROR_SUCCESS )
  263. {
  264. switch ( targetValue.type )
  265. {
  266. case REG_NONE:
  267. {
  268. dwInstallStatus = DET_INSTALLED;
  269. break;
  270. }
  271. case REG_DWORD:
  272. {
  273. if ( (type == REG_DWORD) ||
  274. ((type == REG_BINARY) && (size >= sizeof(DWORD))) )
  275. {
  276. // see if we have a match
  277. if ( targetValue.dw == keyvalue.dw )
  278. {
  279. *pDetection->pdwInstalledVer = 1;
  280. *pDetection->pdwInstalledBuild = 1;
  281. dwInstallStatus = DET_INSTALLED;
  282. }
  283. }
  284. break;
  285. }
  286. case REG_SZ:
  287. {
  288. if ( type == REG_SZ )
  289. {
  290. if ( lstrcmpi(targetValue.sz, keyvalue.sz) == 0 )
  291. {
  292. *pDetection->pdwInstalledVer = 1;
  293. *pDetection->pdwInstalledBuild = 1;
  294. dwInstallStatus = DET_INSTALLED;
  295. }
  296. }
  297. break;
  298. }
  299. } // switch
  300. }
  301. }
  302. }
  303. else
  304. {
  305. // no REG value so, REGPATH is sufficient to determine
  306. // installation.
  307. *pDetection->pdwInstalledVer = 1;
  308. *pDetection->pdwInstalledBuild = 1;
  309. dwInstallStatus = DET_INSTALLED;
  310. }
  311. RegCloseKey(hKey);
  312. }
  313. }
  314. }
  315. }
  316. return dwInstallStatus;
  317. }
  318. /////////////////////////////////////////////////////////////////////////////
  319. // RegKeyVersion (EXPORT)
  320. //
  321. // This API will determine if an application exists based on the
  322. // existence of a version number in the registry.
  323. /////////////////////////////////////////////////////////////////////////////
  324. DWORD WINAPI RegKeyVersion(DETECTION_STRUCT *pDetection)
  325. {
  326. DWORD dwInstallStatus = DET_NOTINSTALLED;
  327. HKEY hKeyRoot;
  328. HKEY hKey;
  329. DWORD type;
  330. TCHAR szTargetKeyName[MAX_PATH];
  331. TCHAR szTargetKeyValue[MAX_PATH];
  332. TCHAR szAskVersion[MAX_PATH];
  333. //TCHAR szVersion[MAX_VERSION_STRING_LEN];
  334. TCHAR szBuf[MAX_PATH];
  335. //DWORD dwStatus;
  336. //DWORD dwLen;
  337. DWORD dwVer;
  338. DWORD dwBuild;
  339. DWORD dwAskVer;
  340. DWORD dwAskBuild;
  341. // make sure the struct is of the expected size
  342. if ( pDetection->dwSize < sizeof(DETECTION_STRUCT) )
  343. {
  344. goto cleanup;
  345. }
  346. // get the registry key name from the components section of the
  347. // CIF file.
  348. if ( FGetCifEntry(pDetection, DETREG_KEY, szBuf, sizeof(szBuf)/sizeof(TCHAR)) &&
  349. (dwKeyType(szBuf, &hKeyRoot, szTargetKeyName, sizeof(szTargetKeyName)/sizeof(TCHAR)) == ERROR_SUCCESS) )
  350. {
  351. if ( RegOpenKeyEx( hKeyRoot,
  352. szTargetKeyName,
  353. 0,
  354. KEY_QUERY_VALUE,
  355. &hKey) == ERROR_SUCCESS )
  356. {
  357. if ( FGetCifEntry(pDetection, DETREG_VERSION, szBuf, sizeof(szBuf)/sizeof(TCHAR)) &&
  358. (GetStringField2(szBuf, 0, szTargetKeyValue, sizeof(szTargetKeyValue)/sizeof(TCHAR)) != 0) )
  359. {
  360. DWORD size = sizeof(szBuf);
  361. if (GetStringField2(szBuf, 1, szAskVersion, sizeof(szAskVersion)/sizeof(TCHAR)) != 0)
  362. {
  363. fConvertDotVersionStrToDwords(szAskVersion, &dwAskVer, &dwAskBuild);
  364. }
  365. else
  366. {
  367. dwAskVer = pDetection->dwAskVer;
  368. dwAskBuild = pDetection->dwAskBuild;
  369. }
  370. if ( RegQueryValueEx(hKey,
  371. szTargetKeyValue,
  372. 0,
  373. &type,
  374. (BYTE *)szBuf,
  375. &size) == ERROR_SUCCESS )
  376. {
  377. if ( type == REG_SZ )
  378. {
  379. fConvertDotVersionStrToDwords(szBuf, &dwVer, &dwBuild);
  380. if ( nCompareVersion(dwVer, dwBuild, dwAskVer, dwAskBuild) >= 0 )
  381. {
  382. *pDetection->pdwInstalledVer = 1;
  383. *pDetection->pdwInstalledBuild = 1;
  384. dwInstallStatus = DET_INSTALLED;
  385. }
  386. }
  387. }
  388. }
  389. RegCloseKey(hKey);
  390. }
  391. }
  392. cleanup:
  393. return dwInstallStatus;
  394. }
  395. /////////////////////////////////////////////////////////////////////////////
  396. // RegKeySubStr (EXPORT)
  397. //
  398. // This API will determine if an application exists based on the
  399. // existence of one of a number of sub strings in the data.
  400. /////////////////////////////////////////////////////////////////////////////
  401. DWORD WINAPI RegKeySubStr(DETECTION_STRUCT *pDetection)
  402. {
  403. DWORD dwInstallStatus = DET_NOTINSTALLED;
  404. HKEY hKeyRoot;
  405. HKEY hKey;
  406. DWORD type;
  407. TCHAR szTargetKeyName[MAX_PATH];
  408. TCHAR szTargetKeyValue[MAX_PATH];
  409. TCHAR szKeyMissingStatus[MAX_PATH];
  410. TCHAR szData[MAX_PATH];
  411. TCHAR szSubStr[MAX_PATH];
  412. //TCHAR szTmp[MAX_PATH];
  413. TCHAR szBuf[MAX_PATH];
  414. //DWORD dwStatus;
  415. //DWORD dwLen;
  416. //DWORD dwVer;
  417. //DWORD dwBuild;
  418. // make sure the struct is of the expected size
  419. if ( pDetection->dwSize < sizeof(DETECTION_STRUCT) )
  420. {
  421. goto cleanup;
  422. }
  423. // get the registry key name from the components section of the
  424. // CIF file.
  425. if ( FGetCifEntry(pDetection, DETREG_KEY, szBuf, sizeof(szBuf)/sizeof(TCHAR)) &&
  426. (dwKeyType(szBuf, &hKeyRoot, szTargetKeyName, sizeof(szTargetKeyName)/sizeof(TCHAR)) == ERROR_SUCCESS) )
  427. {
  428. if ( RegOpenKeyEx( hKeyRoot,
  429. szTargetKeyName,
  430. 0,
  431. KEY_QUERY_VALUE,
  432. &hKey) == ERROR_SUCCESS )
  433. {
  434. if ( FGetCifEntry(pDetection, DETREG_SUBSTR, szBuf, sizeof(szBuf)/sizeof(TCHAR)) &&
  435. (GetStringField2(szBuf, 0, szTargetKeyValue, sizeof(szTargetKeyValue)/sizeof(TCHAR)) != 0) &&
  436. (GetStringField2(szBuf, 1, szKeyMissingStatus, sizeof(szKeyMissingStatus)/sizeof(TCHAR)) != 0) )
  437. {
  438. DWORD size = sizeof(szData);
  439. if ( RegQueryValueEx(hKey,
  440. szTargetKeyValue,
  441. 0,
  442. &type,
  443. (BYTE *)szData,
  444. &size) == ERROR_SUCCESS )
  445. {
  446. if ( type == REG_SZ )
  447. {
  448. _tcslwr(szData);
  449. // iterate thru the substrings looking for a match.
  450. int index = 2;
  451. while ( GetStringField2(szBuf, index, szSubStr, sizeof(szSubStr)/sizeof(TCHAR)) != 0 )
  452. {
  453. _tcslwr(szSubStr);
  454. if ( _tcsstr(szData, szSubStr) != NULL )
  455. {
  456. *pDetection->pdwInstalledVer = 1;
  457. *pDetection->pdwInstalledBuild = 1;
  458. dwInstallStatus = DET_INSTALLED;
  459. goto quit_while;
  460. }
  461. index++;
  462. }
  463. quit_while:;
  464. }
  465. }
  466. else
  467. {
  468. // if we get an error, assume the key does not exist. Note that if
  469. // the status is DETFIELD_NOT_INSTALLED then we don't have to do
  470. // anything since that is the default status.
  471. if ( lstrcmpi(DETFIELD_INSTALLED, szKeyMissingStatus) == 0 )
  472. {
  473. dwInstallStatus = DET_INSTALLED;
  474. }
  475. }
  476. }
  477. RegCloseKey(hKey);
  478. }
  479. }
  480. cleanup:
  481. return dwInstallStatus;
  482. }
  483. /////////////////////////////////////////////////////////////////////////////
  484. // MinFileVersion (EXPORT)
  485. // This API will determine if an application exists based on the
  486. // minimum version of a file.
  487. //
  488. // Parameters:
  489. //
  490. // Comments :
  491. /////////////////////////////////////////////////////////////////////////////
  492. DWORD WINAPI MinFileVersion(DETECTION_STRUCT *pDetection)
  493. {
  494. DWORD dwInstallStatus = DET_INSTALLED;
  495. TCHAR szDllName[MAX_PATH];
  496. TCHAR szVersion[MAX_PATH];
  497. DWORD dwSize;
  498. DWORD dwHandle;
  499. TCHAR *pszVerInfo[MAX_PATH];
  500. VS_FIXEDFILEINFO *vsVerInfo;
  501. UINT uLen;
  502. // make sure the struct is of the expected size
  503. if ( pDetection->dwSize >= sizeof(DETECTION_STRUCT) )
  504. {
  505. // get the dll name and version from the components section of the
  506. // CIF file.
  507. if ( FGetCifEntry(pDetection, DETREG_KEY, szDllName, sizeof(szDllName)/sizeof(TCHAR)) )
  508. {
  509. if ( FGetCifEntry(pDetection, DETREG_VALUE, szVersion, sizeof(szVersion)/sizeof(TCHAR)) )
  510. {
  511. PTSTR pszPoint = szDllName;
  512. PTSTR pszPoint2 = szDllName;
  513. TCHAR szNewDllName[MAX_PATH];
  514. while (*pszPoint != '\0')
  515. {
  516. if (*pszPoint == '%')
  517. {
  518. *pszPoint = '\0';
  519. pszPoint += 1;
  520. pszPoint2 = pszPoint;
  521. while (pszPoint2 != '\0')
  522. {
  523. if (*pszPoint2 == '%')
  524. {
  525. *pszPoint2 = '\0';
  526. pszPoint2 += 1;
  527. break;
  528. }
  529. pszPoint2 += 1;
  530. }
  531. break;
  532. }
  533. pszPoint += 1;
  534. }
  535. if (lstrcmpi(pszPoint, TEXT("11")) == 0)
  536. {
  537. TCHAR szSystemDir[MAX_PATH];
  538. GetSystemDirectory(szSystemDir, sizeof(szSystemDir)/sizeof(TCHAR));
  539. lstrcpy(szNewDllName, szSystemDir);
  540. if ((lstrlen(szSystemDir) + lstrlen(pszPoint2)) < sizeof(szNewDllName)/sizeof(TCHAR))
  541. {
  542. lstrcat(szNewDllName, pszPoint2);
  543. }
  544. }
  545. dwSize = GetFileVersionInfoSize(szNewDllName, &dwHandle);
  546. if (dwSize > 0)
  547. {
  548. if(dwSize > MAX_PATH)
  549. dwSize = MAX_PATH;
  550. GetFileVersionInfo(szNewDllName, dwHandle, dwSize, &pszVerInfo);
  551. VerQueryValue(&pszVerInfo, TEXT("\\"), (void **) &vsVerInfo, &uLen);
  552. DWORD dwDllVersion[4];
  553. DWORD dwCheckVersion[4];
  554. dwDllVersion[0] = HIWORD(vsVerInfo->dwProductVersionMS);
  555. dwDllVersion[1] = LOWORD(vsVerInfo->dwProductVersionMS);
  556. dwDllVersion[2] = HIWORD(vsVerInfo->dwProductVersionLS);
  557. dwDllVersion[3] = LOWORD(vsVerInfo->dwProductVersionLS);
  558. pszPoint = szVersion;
  559. pszPoint2 = szVersion;
  560. INT i = 0;
  561. while (*pszPoint != '\0')
  562. {
  563. if (*pszPoint == ',')
  564. {
  565. *pszPoint = '\0';
  566. dwCheckVersion[i] = _ttol(pszPoint2);
  567. i += 1;
  568. pszPoint2 = pszPoint + 1;
  569. }
  570. pszPoint += 1;
  571. }
  572. dwCheckVersion[i] = _ttol(pszPoint2);
  573. for (i = 0; i < 4; i += 1)
  574. {
  575. if (dwDllVersion[i] < dwCheckVersion[i])
  576. {
  577. dwInstallStatus = DET_NOTINSTALLED;
  578. }
  579. }
  580. } else {
  581. dwInstallStatus = DET_NOTINSTALLED;
  582. }
  583. *pDetection->pdwInstalledVer = 1;
  584. *pDetection->pdwInstalledBuild = 1;
  585. }
  586. }
  587. }
  588. return dwInstallStatus;
  589. }
  590. /////////////////////////////////////////////////////////////////////////////
  591. // Expression (EXPORT)
  592. //
  593. // This API will evaluate a boolean expression where every operand is a
  594. // detection operation.
  595. /////////////////////////////////////////////////////////////////////////////
  596. const DWORD MAX_EXPRESSION_LEN = 1024;
  597. DWORD WINAPI Expression(DETECTION_STRUCT *pDetection)
  598. {
  599. DWORD dwInstallStatus = DET_NOTINSTALLED;
  600. //HKEY hKeyRoot;
  601. //HKEY hKey;
  602. //DWORD type;
  603. //TCHAR szTargetKeyName[MAX_PATH];
  604. //TCHAR szTargetKeyValue[MAX_PATH];
  605. //TCHAR szKeyMissingStatus[MAX_PATH];
  606. //TCHAR szData[MAX_PATH];
  607. //TCHAR szSubStr[MAX_PATH];
  608. //TCHAR szTmp[MAX_PATH];
  609. TCHAR szExpression[MAX_EXPRESSION_LEN];
  610. //DWORD dwStatus;
  611. //DWORD dwLen;
  612. //DWORD dwVer;
  613. //DWORD dwBuild;
  614. // make sure the struct is of the expected size
  615. if ( pDetection->dwSize < sizeof(DETECTION_STRUCT) )
  616. {
  617. goto cleanup;
  618. }
  619. // get the expression.
  620. if ( FGetCifEntry(pDetection, DET_EXPRESSION, szExpression, sizeof(szExpression)/sizeof(TCHAR)) )
  621. {
  622. CExpressionParser expression(pDetection);
  623. bool fResult = TRUE;
  624. HRESULT hr = expression.fEvalExpression(szExpression, &fResult);
  625. if ( SUCCEEDED(hr) && fResult)
  626. {
  627. *pDetection->pdwInstalledVer = 1;
  628. *pDetection->pdwInstalledBuild = 1;
  629. dwInstallStatus = DET_INSTALLED;
  630. }
  631. }
  632. cleanup:
  633. return dwInstallStatus;
  634. }