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.

993 lines
34 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: ddwarn.cpp
  7. //
  8. // Contents: implementation of CDlgDependencyWarn
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "snapmgr.h"
  13. #include "cookie.h"
  14. #include "DDWarn.h"
  15. #include "util.h"
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CDlgDependencyWarn dialog
  23. CDlgDependencyWarn::CDlgDependencyWarn(CWnd* pParent /*=NULL*/)
  24. : CHelpDialog(a238HelpIDs, IDD, pParent)
  25. {
  26. m_pResult = NULL;
  27. m_dwValue = SCE_NO_VALUE;
  28. //{{AFX_DATA_INIT(CDlgDependencyWarn)
  29. // NOTE: the ClassWizard will add member initialization here
  30. //}}AFX_DATA_INIT
  31. }
  32. CDlgDependencyWarn::~CDlgDependencyWarn()
  33. {
  34. for(int iCheck = 0; iCheck < m_aFailedList.GetSize(); iCheck++){
  35. if(m_aFailedList[iCheck]){
  36. LocalFree(m_aFailedList[iCheck]);
  37. }
  38. }
  39. m_aFailedList.RemoveAll();
  40. for(int iCheck = 0; iCheck < m_aDependsList.GetSize(); iCheck++){
  41. if(m_aDependsList[iCheck]){
  42. m_aDependsList[iCheck]->Release();
  43. }
  44. }
  45. m_aDependsList.RemoveAll();
  46. }
  47. void CDlgDependencyWarn::DoDataExchange(CDataExchange* pDX)
  48. {
  49. CDialog::DoDataExchange(pDX);
  50. //{{AFX_DATA_MAP(CDlgDependencyWarn)
  51. // NOTE: the ClassWizard will add DDX and DDV calls here
  52. //}}AFX_DATA_MAP
  53. }
  54. //////////////////////////////////////////////////////////////////////////////////////
  55. // CDlgDependencyWarn::m_aMinMaxInfo
  56. // Min max info for items.
  57. //////////////////////////////////////////////////////////////////////////////////////
  58. DEPENDENCYMINMAX CDlgDependencyWarn::m_aMinMaxInfo [] =
  59. {
  60. // ID // Min value // Max Value // Increment by //Flags
  61. { IDS_LOCK_DURATION, 1, 99999, 1},
  62. { IDS_MIN_PAS_AGE, 0, 998, 1},
  63. { IDS_MAX_PAS_AGE, 0, 999, 1},
  64. { IDS_LOCK_COUNT, 0, 999, 1},
  65. { IDS_MIN_PAS_LEN, 0, 14, 1},
  66. { IDS_PAS_UNIQUENESS, 0, 24, 1},
  67. { IDS_LOCK_RESET_COUNT, 1, 99999, 1},
  68. { IDS_SYS_LOG_MAX, 64, 4194240, 64},
  69. { IDS_SEC_LOG_MAX, 64, 4194240, 64},
  70. { IDS_APP_LOG_MAX, 64, 4194240, 64},
  71. { IDS_SYS_LOG_DAYS, 1, 365, 1},
  72. { IDS_SEC_LOG_DAYS, 1, 365, 1},
  73. { IDS_APP_LOG_DAYS, 1, 365, 1},
  74. { IDS_KERBEROS_MAX_AGE, 1, 99999, 1},
  75. { IDS_KERBEROS_RENEWAL, 1, 99999, 1},
  76. { IDS_KERBEROS_MAX_SERVICE, 10, 99999, 1},
  77. { IDS_KERBEROS_MAX_CLOCK, 0, 99999, 1}
  78. };
  79. //+------------------------------------------------------------------------------------
  80. // CDlgDependencyWarn::GetMinMaxInfo
  81. //
  82. // Returns the row which contains the [uID]
  83. //
  84. // Arguments: [uID] - The ID to search for.
  85. //
  86. // Returns: A row pointer or NULL if the ID is not contained in the table.
  87. //-------------------------------------------------------------------------------------
  88. const DEPENDENCYMINMAX *
  89. CDlgDependencyWarn::LookupMinMaxInfo(UINT uID)
  90. {
  91. int nSize = sizeof(m_aMinMaxInfo)/sizeof(DEPENDENCYMINMAX);
  92. for(int i = 0; i < nSize; i++){
  93. if(m_aMinMaxInfo[i].uID == uID){
  94. return &(m_aMinMaxInfo[i]);
  95. }
  96. }
  97. return NULL;
  98. }
  99. //////////////////////////////////////////////////////////////////////////////////////
  100. // The dependency list.
  101. // The ID defines what we are checking.
  102. // The Dependent IDS are the items the item is dependent on.
  103. // Count - The number of dependencies.
  104. // Default - The default value for the item if no other values can be used.
  105. // This is only used if the Item must be configured and it is not.
  106. // Conversion - What units the item must be converted to before performing the check.
  107. // Operator -
  108. //////////////////////////////////////////////////////////////////////////////////////
  109. DEPENDENCYLIST g_aDList [] =
  110. {
  111. // ID // Depend ID //Count/Default/Conversion //Check type
  112. //
  113. // Password reset count <= password Lock duratio, and Password lock count must be
  114. // configured.
  115. //
  116. { IDS_LOCK_RESET_COUNT, IDS_LOCK_DURATION, 4, 30, 1, DPCHECK_GREATEREQUAL |
  117. DPCHECK_VALIDFOR_NC},
  118. { 0, IDS_LOCK_COUNT, 0, 5, 1, DPCHECK_CONFIGURED|DPCHECK_NEVER },
  119. { 0, IDS_LOCK_DURATION, 0, 0, 1, DPCHECK_NOTCONFIGURED},
  120. { 0, IDS_LOCK_COUNT, 0, 0, 1, DPCHECK_NOTCONFIGURED|DPCHECK_NEVER},
  121. //
  122. // Password lock duration, Reset count must be <=, and if this item is not configured,
  123. // then Reset Count is also not configured.
  124. //
  125. { IDS_LOCK_DURATION, IDS_LOCK_RESET_COUNT, 4, 30, 1, DPCHECK_LESSEQUAL |
  126. DPCHECK_VALIDFOR_NC},
  127. { 0, IDS_LOCK_COUNT, 0, 5, 1, DPCHECK_CONFIGURED|DPCHECK_NEVER},
  128. { 0, IDS_LOCK_RESET_COUNT, 0, 5, 1, DPCHECK_NOTCONFIGURED},
  129. { 0, IDS_LOCK_COUNT, 0, 5, 1, DPCHECK_NOTCONFIGURED|DPCHECK_NEVER},
  130. //
  131. // Password Lock count. If this item is configured then both Lock count and reset
  132. // should be configured. If it is not configured or 0 then the above items can not
  133. // configured.
  134. //
  135. { IDS_LOCK_COUNT, IDS_LOCK_DURATION, 4, 0, 1, DPCHECK_NOTCONFIGURED|DPCHECK_NEVER},
  136. { 0, IDS_LOCK_RESET_COUNT, 0, 0, 1, DPCHECK_NOTCONFIGURED|DPCHECK_NEVER},
  137. { 0, IDS_LOCK_DURATION, 0, 30,1, DPCHECK_CONFIGURED|DPCHECK_NEVER},
  138. { 0, IDS_LOCK_RESET_COUNT, 0, 30,1, DPCHECK_CONFIGURED|DPCHECK_NEVER},
  139. //
  140. // Kerberos Max ticket age is dependent on all three things being set.
  141. //
  142. { IDS_KERBEROS_MAX_AGE, IDS_KERBEROS_RENEWAL, 4, 7, 24, DPCHECK_GREATEREQUAL |
  143. DPCHECK_FOREVER | DPCHECK_VALIDFOR_NC},
  144. { 0, IDS_KERBEROS_MAX_SERVICE, 0, 10, 60, DPCHECK_LESSEQUAL |
  145. DPCHECK_FOREVER | DPCHECK_INVERSE | DPCHECK_VALIDFOR_NC},
  146. { 0, IDS_KERBEROS_RENEWAL, 0, 0, 1, DPCHECK_NOTCONFIGURED},
  147. { 0, IDS_KERBEROS_MAX_SERVICE, 0, 0, 1, DPCHECK_NOTCONFIGURED},
  148. //
  149. // Kerberos renewel is dependent on all three things being set.
  150. //
  151. { IDS_KERBEROS_RENEWAL, IDS_KERBEROS_MAX_AGE, 4, 0, 24, DPCHECK_NOTCONFIGURED},
  152. { 0, IDS_KERBEROS_MAX_SERVICE, 0, 0, 1440, DPCHECK_NOTCONFIGURED},
  153. { 0, IDS_KERBEROS_MAX_AGE, 0, 7, 24, DPCHECK_LESSEQUAL | DPCHECK_VALIDFOR_NC |
  154. DPCHECK_FOREVER | DPCHECK_INVERSE },
  155. { 0, IDS_KERBEROS_MAX_SERVICE, 0, 10, 1440, DPCHECK_LESSEQUAL | DPCHECK_VALIDFOR_NC |
  156. DPCHECK_FOREVER | DPCHECK_INVERSE },
  157. //
  158. // Kerberose max service age is dependent on all three being set.
  159. //
  160. { IDS_KERBEROS_MAX_SERVICE, IDS_KERBEROS_MAX_AGE, 4, 7, 60, DPCHECK_GREATEREQUAL |
  161. DPCHECK_VALIDFOR_NC},
  162. { 0, IDS_KERBEROS_RENEWAL, 0, 10, 1440, DPCHECK_GREATEREQUAL |
  163. DPCHECK_VALIDFOR_NC },
  164. { 0, IDS_KERBEROS_RENEWAL, 0, 0, 1, DPCHECK_NOTCONFIGURED},
  165. { 0, IDS_KERBEROS_MAX_AGE, 0, 0, 1, DPCHECK_NOTCONFIGURED},
  166. //
  167. // Password min age is dependent on password max age being set.
  168. //
  169. { IDS_MIN_PAS_AGE, IDS_MAX_PAS_AGE, 2, 30, 1, DPCHECK_GREATER | DPCHECK_FOREVER |
  170. DPCHECK_VALIDFOR_NC},
  171. { 0, IDS_MAX_PAS_AGE, 0, 0, 1, DPCHECK_NOTCONFIGURED},
  172. //
  173. // Password max age is dependent on password min age being set.
  174. //
  175. { IDS_MAX_PAS_AGE, IDS_MIN_PAS_AGE, 2, 30, 1, DPCHECK_LESS | DPCHECK_FOREVER |
  176. DPCHECK_VALIDFOR_NC},
  177. { 0, IDS_MIN_PAS_AGE, 0, 0, 1, DPCHECK_NOTCONFIGURED},
  178. //
  179. //"Retention method for application log" is dependent on
  180. //"Retain Application Log for
  181. //
  182. { IDS_APP_LOG_RET, IDS_APP_LOG_DAYS, 2, 7, 1, DPCHECK_RETENTION_METHOD_CONFIGURED },
  183. { 0, IDS_APP_LOG_DAYS, 0, 0, 1, DPCHECK_RETENTION_METHOD_NOTCONFIGURED },
  184. { IDS_SEC_LOG_RET, IDS_SEC_LOG_DAYS, 2, 7, 1, DPCHECK_RETENTION_METHOD_CONFIGURED },
  185. { 0, IDS_SEC_LOG_DAYS, 0, 0, 1, DPCHECK_RETENTION_METHOD_NOTCONFIGURED },
  186. { IDS_SYS_LOG_RET, IDS_SYS_LOG_DAYS, 2, 7, 1, DPCHECK_RETENTION_METHOD_CONFIGURED },
  187. { 0, IDS_SYS_LOG_DAYS, 0, 0, 1, DPCHECK_RETENTION_METHOD_NOTCONFIGURED },
  188. //
  189. //"Retain Application Log for is dependent on
  190. //"Retention method for application log"
  191. //
  192. { IDS_APP_LOG_DAYS, IDS_APP_LOG_RET, 2, SCE_RETAIN_BY_DAYS, 1, DPCHECK_RETAIN_FOR_CONFIGURED },
  193. { 0, IDS_APP_LOG_RET, 0, 0, 1, DPCHECK_RETAIN_FOR_NOTCONFIGURED },
  194. { IDS_SEC_LOG_DAYS, IDS_SEC_LOG_RET, 2, SCE_RETAIN_BY_DAYS, 1, DPCHECK_RETAIN_FOR_CONFIGURED },
  195. { 0, IDS_SEC_LOG_RET, 0, 0, 1, DPCHECK_RETAIN_FOR_NOTCONFIGURED },
  196. { IDS_SYS_LOG_DAYS, IDS_SYS_LOG_RET, 2, SCE_RETAIN_BY_DAYS, 1, DPCHECK_RETAIN_FOR_CONFIGURED },
  197. { 0, IDS_SYS_LOG_RET, 0, 0, 1, DPCHECK_RETAIN_FOR_NOTCONFIGURED }
  198. };
  199. //+------------------------------------------------------------------------------------
  200. // CDlgDependencyWarn::InitializeDependancies
  201. //
  202. // Initialize the dependancies check. This needs to be done immediately when the
  203. // property sheet whose dependancies we'll want to check is created because it
  204. // ensures that all of the result items who this attribute is dependant on stick
  205. // around.
  206. //
  207. // Arguments [pSnapin] - The snapin which is associated with the CREsult item.
  208. // [pResult] - The result item we are checking.
  209. // [pList] - An alternate dependancy list to use
  210. // [iCount] - The size of the alternate dependancy list
  211. // Returns:
  212. // ERROR_SUCCESS - Everything initialized properly
  213. // ERROR_INVALID_PARAMETER - Either [pSnapin] or [pResult] is NULL.
  214. //-------------------------------------------------------------------------------------
  215. DWORD
  216. CDlgDependencyWarn::InitializeDependencies(
  217. CSnapin *pSnapin, // The snapin who owns the CResult item.
  218. CResult *pResult, // The CResult item we are checking
  219. PDEPENDENCYLIST pList,// The Dependency list check.
  220. int iCount // The count of dependencies in the list.
  221. )
  222. {
  223. if( !pSnapin || !pResult){
  224. return ERROR_INVALID_PARAMETER;
  225. }
  226. m_pResult = pResult;
  227. m_pSnapin = pSnapin;
  228. //
  229. // If no dependency list is passed in then set it to the default one.
  230. //
  231. if(!pList){
  232. pList = g_aDList;
  233. iCount = sizeof(g_aDList)/sizeof(DEPENDENCYLIST);
  234. }
  235. //
  236. // Find the item in the table.
  237. //
  238. for(int i = 0; i < iCount; i++){
  239. if( pList[i].uID == (UINT)pResult->GetID() ){
  240. break;
  241. }
  242. i += (pList[i].uDependencyCount - 1);
  243. }
  244. //
  245. // No dependencies for this item
  246. //
  247. if( i >= iCount){
  248. m_pList = NULL;
  249. m_iCount = 0;
  250. return ERROR_SUCCESS;
  251. }
  252. //
  253. // Count of dependencies for the item.
  254. //
  255. m_iCount = pList[i].uDependencyCount;
  256. m_pList = &(pList[i]);
  257. CResult *pDepends = NULL;
  258. //
  259. // Check each dependency.
  260. //
  261. pList = m_pList;
  262. for(int iCheck = 0;
  263. iCheck < m_iCount;
  264. iCheck++, pList++){
  265. pDepends = GetResultItem( pResult, pList->uDepends );
  266. if(pDepends){
  267. //
  268. // We're going to need this dependant item later
  269. //
  270. pDepends->AddRef();
  271. m_aDependsList.Add( pDepends );
  272. }
  273. }
  274. return ERROR_SUCCESS;
  275. }
  276. //+------------------------------------------------------------------------------------
  277. // CDlgDependencyWarn::CheckDendencies
  278. //
  279. // This function is used to see if all the dependencies for the result value
  280. // are met. If a check fails then the function returns ERROR_MORE_DATA and
  281. // the calling procedure can optionally display more information through the dialog
  282. // box. The function also creates suggested values that would meet the
  283. // dependencies as specifide in the dependency table.
  284. //
  285. // Arguments:
  286. // [dwValue] - The new value.
  287. // Returns:
  288. // ERROR_SUCCESS - The value is fine or there is no record in the table.
  289. // ERROR_MORE_DATA - At least of of the dependency checks failed.
  290. // ERROR_NOT_READY - InitializeDependencies hasn't yet been called
  291. //-------------------------------------------------------------------------------------
  292. DWORD
  293. CDlgDependencyWarn::CheckDependencies(
  294. DWORD dwValue // The value we are checking.
  295. )
  296. {
  297. if( !m_pSnapin || !m_pResult) {
  298. return ERROR_NOT_READY;
  299. }
  300. if (!m_pList) {
  301. //
  302. // No Dependancies
  303. //
  304. return ERROR_SUCCESS;
  305. }
  306. //
  307. // Save this information for later use, just in case the dialog box is displayed.
  308. //
  309. m_dwValue = dwValue;
  310. //
  311. // Free up the dependency array, as it is no longer valid when this function
  312. // starts.
  313. //
  314. CResult *pDepends = NULL;
  315. for(int iCheck = 0; iCheck < m_aFailedList.GetSize(); iCheck++){
  316. if(m_aFailedList[iCheck]){
  317. LocalFree(m_aFailedList[iCheck]);
  318. }
  319. }
  320. m_aFailedList.RemoveAll();
  321. //
  322. // Check each dependency.
  323. //
  324. PDEPENDENCYLIST pList = m_pList;
  325. for(int iCheck = 0; iCheck < m_aDependsList.GetSize(); iCheck++,pList++){
  326. ASSERT(pList->uConversion != 0);
  327. pDepends = m_aDependsList[iCheck];
  328. if(pDepends){
  329. //
  330. // perform check.
  331. //
  332. BOOL bFailed = FALSE;
  333. DWORD dwCheck = 0;
  334. DWORD dwItem = 0;
  335. LONG_PTR dwSuggest = 0;
  336. BOOL bNever = 0;
  337. BOOL bSourceConfigured;
  338. BOOL bDependConfigured;
  339. switch( 0x0000FFFF & pList->uOpFlags ){
  340. case DPCHECK_CONFIGURED:
  341. //Rule:if the source is configured, depend must be configured
  342. //
  343. // The depent item must be configured. Failure accurs only if the items
  344. // value is some error value of SCE.
  345. //
  346. dwSuggest = (LONG_PTR)pList->uDefault;
  347. bNever = pList->uOpFlags & DPCHECK_NEVER;
  348. dwCheck = (DWORD) pDepends->GetBase();
  349. //check if source is configured
  350. if (SCE_NO_VALUE == dwValue || SCE_ERROR_VALUE == dwValue) {
  351. // this item is not configured
  352. bSourceConfigured = FALSE;
  353. }
  354. else if( 0 == dwValue && bNever ){
  355. bSourceConfigured = FALSE;
  356. }
  357. else{
  358. bSourceConfigured = true;
  359. }
  360. //check if depend is configured
  361. if (SCE_NO_VALUE == dwCheck || SCE_ERROR_VALUE == dwCheck) {
  362. // the dependant item is not configured
  363. bDependConfigured = false;
  364. } else if ( 0 == dwCheck && bNever ) {
  365. // the dependant item is not configured if bNever is true
  366. bDependConfigured = false;
  367. }
  368. else{
  369. bDependConfigured = true;
  370. }
  371. bFailed = bSourceConfigured ? !bDependConfigured : false;
  372. break;
  373. case DPCHECK_NOTCONFIGURED:
  374. //Rule: if source is not configured, depend should not be
  375. //configured
  376. dwSuggest = (LONG_PTR)SCE_NO_VALUE;
  377. bNever = pList->uOpFlags & DPCHECK_NEVER;
  378. dwCheck = (DWORD) pDepends->GetBase();
  379. //check if source is configured
  380. if (SCE_NO_VALUE == dwValue ) {
  381. // this item is not configured
  382. bSourceConfigured = FALSE;
  383. }
  384. else if( 0 == dwValue && bNever ){
  385. bSourceConfigured = FALSE;
  386. }
  387. else{
  388. bSourceConfigured = true;
  389. }
  390. //check if depend is configured
  391. if (SCE_NO_VALUE == dwCheck ) {
  392. // the dependant item is not configured
  393. bDependConfigured = false;
  394. } else if ( 0 == dwCheck && bNever ) {
  395. // the dependant item is not configured if bNever is true
  396. bDependConfigured = false;
  397. }
  398. else{
  399. bDependConfigured = true;
  400. }
  401. bFailed = bSourceConfigured ? false : bDependConfigured;
  402. break;
  403. //This case statement is Specially for retention method case
  404. case DPCHECK_RETENTION_METHOD_CONFIGURED:
  405. //Here is the rule for DPCHECK_RETENTION_METHOD_CONFIGURED and DPCHECK_RETENTION_METHOD_NOTCONFIGURED
  406. //If and Only if "Overwrite Event by days" is checked
  407. //Retain **** Log for is configured
  408. //Rule:if the source is configured, depend must be configured
  409. dwSuggest = (LONG_PTR)pList->uDefault;
  410. dwCheck = (DWORD) pDepends->GetBase();
  411. //check if source is configured
  412. if ( SCE_RETAIN_BY_DAYS == dwValue )
  413. bSourceConfigured = true;
  414. else
  415. bSourceConfigured = false;
  416. //check if depend is configured
  417. if (SCE_NO_VALUE == dwCheck || SCE_ERROR_VALUE == dwCheck)
  418. bDependConfigured = false;
  419. else
  420. bDependConfigured = true;
  421. bFailed = bSourceConfigured ? !bDependConfigured : false;
  422. break;
  423. case DPCHECK_RETENTION_METHOD_NOTCONFIGURED:
  424. //Rule: if source is not configured, depend should not be
  425. //configured
  426. dwSuggest = (LONG_PTR)SCE_NO_VALUE;
  427. dwCheck = (DWORD) pDepends->GetBase();
  428. //check if source is configured
  429. if (SCE_RETAIN_BY_DAYS == dwValue )
  430. bSourceConfigured = true;
  431. else
  432. bSourceConfigured = false;
  433. //check if depend is configured
  434. if (SCE_NO_VALUE == dwCheck || SCE_ERROR_VALUE == dwCheck)
  435. bDependConfigured = false;
  436. else
  437. bDependConfigured = true;
  438. bFailed = bSourceConfigured ? false : bDependConfigured;
  439. break;
  440. //This case statement is Specially for Retain *** Log For case
  441. case DPCHECK_RETAIN_FOR_CONFIGURED:
  442. //Here is the rule for DPCHECK_RETAIN_FOR_CONFIGURED and DPCHECK_RETAIN_FOR_NOTCONFIGURED
  443. //If "Retain **** Log for" is configured
  444. //then "Overwrite Event by days" is checked
  445. dwSuggest = (LONG_PTR)pList->uDefault;
  446. dwCheck = (DWORD) pDepends->GetBase();
  447. //check if source is configured
  448. if (SCE_NO_VALUE == dwValue || SCE_ERROR_VALUE == dwValue)
  449. bSourceConfigured = false;
  450. else
  451. bSourceConfigured = true;
  452. //check if depend is configured
  453. if (SCE_RETAIN_BY_DAYS == dwCheck )
  454. bDependConfigured = true;
  455. else
  456. bDependConfigured = false;
  457. bFailed = bSourceConfigured ? !bDependConfigured : false;
  458. break;
  459. case DPCHECK_RETAIN_FOR_NOTCONFIGURED:
  460. //Rule: if source is not configured, depend should not be
  461. //configured
  462. dwSuggest = (LONG_PTR)SCE_NO_VALUE;
  463. dwCheck = (DWORD) pDepends->GetBase();
  464. //check if source is configured
  465. if (SCE_NO_VALUE == dwValue || SCE_ERROR_VALUE == dwValue)
  466. bSourceConfigured = false;
  467. else
  468. bSourceConfigured = true;
  469. //check if depend is configured
  470. if (SCE_RETAIN_BY_DAYS == dwCheck )
  471. bDependConfigured = true;
  472. else
  473. bDependConfigured = false;
  474. bFailed = bSourceConfigured ? false : bDependConfigured;
  475. break;
  476. default:
  477. //
  478. // convert the values as needed. If the check value is NOT Configured,
  479. // Then we don't have anything to do, unless the item must be configured
  480. // for the value to be correct. This is specifide by DPCHECK_VALIDFOR_NC
  481. // being set. At this point, if the depend item is not configured then
  482. // we will set the check item to the default value. We will allow the
  483. // check to be performed, (mostly because we need to get the suggested value.
  484. //
  485. dwItem = dwValue;
  486. dwCheck = (DWORD)pDepends->GetBase();
  487. if( (!(pList->uOpFlags & DPCHECK_VALIDFOR_NC)
  488. && dwCheck == SCE_NO_VALUE) || dwItem == SCE_NO_VALUE ){
  489. //
  490. // The dependent item is not configured and DPCHECK_VALIDFOR_NC is
  491. // not set, nothing to do.
  492. continue;
  493. } else if(dwCheck == SCE_NO_VALUE){
  494. //
  495. // Set the suggested value to the default specifide in the table.
  496. //
  497. if(pList->uOpFlags & DPCHECK_INVERSE){
  498. dwSuggest = (LONG_PTR) ((DWORD)pList->uDefault/ m_pList->uConversion);
  499. } else {
  500. dwSuggest = (LONG_PTR) ((DWORD)pList->uDefault * m_pList->uConversion);
  501. }
  502. dwCheck = pList->uDefault;
  503. }
  504. if( pList->uOpFlags & DPCHECK_FOREVER){
  505. //
  506. // Convert values to maximum natural number.
  507. //
  508. if(dwItem == SCE_FOREVER_VALUE){
  509. dwItem = -1;
  510. }
  511. //
  512. // The value to check against.
  513. //
  514. if(dwCheck == SCE_FOREVER_VALUE){
  515. dwCheck = -1;
  516. } else {
  517. goto ConvertUnits;
  518. }
  519. } else {
  520. ConvertUnits:
  521. //
  522. // Normal conversion routine. We need to convert the number to
  523. // the item we are checkings units.
  524. //
  525. if(pList->uOpFlags & DPCHECK_INVERSE){
  526. //
  527. // When deviding by integers we want to round up, not down.
  528. //
  529. dwCheck = (DWORD)(dwCheck / pList->uConversion) + (dwCheck%m_pList->uConversion ? 1:0);
  530. } else {
  531. dwCheck = (DWORD)(dwCheck * pList->uConversion);
  532. }
  533. }
  534. switch( 0x0000FFFF & pList->uOpFlags ){
  535. case DPCHECK_GREATEREQUAL:
  536. //
  537. // Fails only if the dependency value is less than the item we
  538. // are checking.
  539. //
  540. if( dwCheck < dwItem){
  541. dwSuggest = (LONG_PTR)dwValue;
  542. bFailed = TRUE;
  543. }
  544. break;
  545. case DPCHECK_GREATER:
  546. //
  547. // Fails only if the dependency value is less than or equal to
  548. // the item we are checking.
  549. //
  550. if( dwCheck <= dwItem){
  551. dwSuggest = (LONG_PTR)(dwValue + 1);
  552. bFailed = TRUE;
  553. }
  554. break;
  555. case DPCHECK_LESSEQUAL:
  556. //
  557. // Fails if the dependency value is greater than the value.
  558. //
  559. if( dwCheck > dwItem ){
  560. dwSuggest = (LONG_PTR)dwValue;
  561. bFailed = TRUE;
  562. }
  563. break;
  564. case DPCHECK_LESS:
  565. //
  566. // Fails if the dependency value is greater than or equal to the value.
  567. //
  568. if( dwCheck >= dwItem ){
  569. dwSuggest = (LONG_PTR)dwValue - 1;
  570. bFailed = TRUE;
  571. }
  572. break;
  573. }
  574. //
  575. // We do one more final check on the dependency value. If the dependency value
  576. // is not configured or an error then we know the test failed.
  577. // so set the bFailed flag. The suggested value has already been set at
  578. // this point.
  579. //
  580. if( pDepends->GetBase() == (LONG_PTR)SCE_NO_VALUE ||
  581. pDepends->GetBase() == (LONG_PTR)SCE_ERROR_VALUE ){
  582. bFailed = TRUE;
  583. }
  584. }
  585. if(bFailed){
  586. //
  587. // The check failed so add the item to the failed list.
  588. //
  589. dwItem = (DWORD)dwSuggest;
  590. //
  591. // Calculate the actual value.
  592. //
  593. if(dwItem == -1 && pList->uOpFlags & DPCHECK_FOREVER){
  594. //
  595. // Special case for forever value.
  596. dwSuggest = (LONG_PTR)SCE_FOREVER_VALUE;
  597. } else if(dwItem != SCE_NO_VALUE){
  598. //
  599. // Other values must be converted back to their units.
  600. //
  601. if(pList->uOpFlags & DPCHECK_INVERSE){
  602. dwSuggest = (LONG_PTR) (dwItem * pList->uConversion);
  603. } else {
  604. if(dwItem%pList->uConversion){
  605. dwSuggest = (LONG_PTR) ((dwItem + pList->uConversion)/m_pList->uConversion);
  606. } else {
  607. dwSuggest = (LONG_PTR) ((dwItem)/pList->uConversion);
  608. }
  609. }
  610. }
  611. //
  612. // check bounds on suggested settings.
  613. //
  614. const DEPENDENCYMINMAX *pMinMax = LookupMinMaxInfo( (UINT)pDepends->GetID());
  615. if(pMinMax && dwSuggest != SCE_NO_VALUE && dwSuggest != SCE_FOREVER_VALUE){
  616. if(pMinMax->uMin > (UINT)dwSuggest){
  617. dwSuggest = pMinMax->uMin;
  618. } else if( pMinMax->uMax < (UINT)dwSuggest ){
  619. dwSuggest = pMinMax->uMax;
  620. }
  621. }
  622. if( pDepends->GetBase() != dwSuggest ) //Raid #402030
  623. {
  624. PDEPENDENCYFAILED pAdd = (PDEPENDENCYFAILED)LocalAlloc(0, sizeof(DEPENDENCYFAILED));
  625. if(pAdd){
  626. //
  627. // Add the item to the failed list.
  628. //
  629. pAdd->pList = pList;
  630. pAdd->pResult = pDepends;
  631. pAdd->dwSuggested = dwSuggest;
  632. m_aFailedList.Add( pAdd );
  633. }
  634. }
  635. }
  636. }
  637. }
  638. //
  639. // Returns ERROR_MORE_DATA if one of the dependencies failed.
  640. //
  641. if(m_aFailedList.GetSize()){
  642. return ERROR_MORE_DATA;
  643. }
  644. return ERROR_SUCCESS;
  645. }
  646. //+------------------------------------------------------------------------------------
  647. // CDlgDependencyWarn::GetResultItem
  648. //
  649. // Returns the first result item associated with [pBase] with matching
  650. // [uID] throught CResult::GetID();
  651. // Arguments [pBase] - To get the CFolder object.
  652. // [uID] - The ID we are looking for.
  653. // Returns:
  654. // If the function succeeds then a valid CREsult item is returned otherwise
  655. // NULL
  656. //-------------------------------------------------------------------------------------
  657. CResult *
  658. CDlgDependencyWarn::GetResultItem(CResult *pBase, UINT uID)
  659. {
  660. if(!pBase){
  661. return NULL;
  662. }
  663. CFolder *pFolder = reinterpret_cast<CFolder *>(pBase->GetCookie());
  664. if(!pFolder){
  665. //
  666. // Nothing to do.
  667. //
  668. return NULL;
  669. }
  670. HANDLE handle;
  671. pFolder->GetResultItemHandle ( &handle );
  672. if(!handle){
  673. //
  674. // Nothing to do.
  675. //
  676. return NULL;
  677. }
  678. POSITION pos = NULL;
  679. //
  680. // Enumerate through all the result items and find out if any of them
  681. // matches the ID. If so then return the item.
  682. //
  683. pFolder->GetResultItem (handle, pos, &pBase);
  684. while(pBase){
  685. if( (UINT)pBase->GetID() == uID){
  686. break;
  687. }
  688. if(!pos){
  689. pBase = NULL;
  690. break;
  691. }
  692. pFolder->GetResultItem(handle, pos, &pBase);
  693. }
  694. pFolder->ReleaseResultItemHandle (handle);
  695. return pBase;
  696. }
  697. BEGIN_MESSAGE_MAP(CDlgDependencyWarn, CHelpDialog)
  698. //{{AFX_MSG_MAP(CDlgDependencyWarn)
  699. //}}AFX_MSG_MAP
  700. END_MESSAGE_MAP()
  701. /////////////////////////////////////////////////////////////////////////////
  702. // CDlgDependencyWarn message handlers
  703. //+-------------------------------------------------------------------------
  704. // CDlgDependencyWarn::OnInitDialog
  705. //
  706. // When this dialog is initialized. We prepare the listctrl for display.
  707. // Set the title of the window and the static window that displays
  708. // information text for the user.
  709. // Create the columns in the list ctrl.
  710. // For each dependency that failed, Insert the item into the list ctrl,
  711. // and set each columns text, by querying the string from the specifide
  712. // result item.
  713. //
  714. // Returns: the default.
  715. BOOL CDlgDependencyWarn::OnInitDialog()
  716. {
  717. CDialog::OnInitDialog();
  718. if(!m_pResult){
  719. //
  720. // Nothing to do.
  721. //
  722. return TRUE;
  723. }
  724. CWnd *pWnd = GetDlgItem(IDC_WARNING);
  725. CListCtrl *pCtrl = reinterpret_cast<CListCtrl *>(GetDlgItem(IDC_FAILEDLIST));
  726. CString str, strVal, strTitle, strFormat;
  727. GetWindowText(str);
  728. //
  729. // Set the window text
  730. GetResultItemString(strTitle, 0, m_pResult);
  731. GetResultItemString(strVal, 1, m_pResult, (LONG_PTR)m_dwValue);
  732. strFormat.Format( str, strTitle );
  733. SetWindowText(strFormat);
  734. if(pWnd){
  735. //
  736. // Set the description text.
  737. //
  738. pWnd->GetWindowText(str);
  739. strFormat.Format( str, strTitle, strVal );
  740. pWnd->SetWindowText(strFormat);
  741. }
  742. int iItem = 0;
  743. if(pCtrl){
  744. //
  745. // Insert the columns.
  746. //
  747. CRect rect;
  748. pCtrl->GetWindowRect(rect);
  749. str.LoadString(IDS_ATTR);
  750. iItem = (int)(rect.Width() * 0.45);
  751. pCtrl->InsertColumn(0, str, LVCFMT_LEFT, iItem);
  752. str.LoadString(IDS_BASE_ANALYSIS);
  753. rect.left += iItem;
  754. iItem = rect.Width()/2;
  755. pCtrl->InsertColumn(1, str, LVCFMT_LEFT, iItem);
  756. str.LoadString(IDS_SUGGESTSETTING);
  757. rect.left += iItem;
  758. pCtrl->InsertColumn(2, str, LVCFMT_LEFT, rect.Width());
  759. }
  760. //
  761. // Create image list for this dialog.
  762. //
  763. CBitmap bmp;
  764. if(bmp.LoadBitmap(IDB_ICON16)){
  765. CDC *dc = GetDC();
  766. CDC bmDC;
  767. if ( bmDC.CreateCompatibleDC(dc) ) {
  768. CBitmap *obmp = bmDC.SelectObject(&bmp);
  769. COLORREF cr = bmDC.GetPixel(0, 0);
  770. bmDC.SelectObject(obmp);
  771. bmp.DeleteObject();
  772. m_imgList.Create(IDB_ICON16, 16, 0, cr);
  773. pCtrl->SetImageList(&m_imgList, LVSIL_SMALL);
  774. }
  775. ReleaseDC(dc);
  776. }
  777. CFolder *pFolder = reinterpret_cast<CFolder *>(m_pResult->GetCookie());
  778. if(pFolder){
  779. //
  780. // Add the items to the error list.
  781. //
  782. for(int i = 0; i < m_aFailedList.GetSize(); i++){
  783. if(!m_aFailedList[i]){
  784. continue;
  785. }
  786. CResult *pDepend = m_aFailedList[i]->pResult;
  787. if(pDepend){
  788. //
  789. // First column text.
  790. //
  791. pDepend->GetDisplayName(NULL, str, 0);
  792. int dwStatus = pDepend->GetStatus();
  793. pDepend->SetStatus(SCE_STATUS_NOT_CONFIGURED);
  794. iItem = pCtrl->InsertItem(0, str, GetResultImageIndex(pFolder, pDepend) );
  795. pDepend->SetStatus( dwStatus );
  796. //
  797. // Second column text.
  798. //
  799. GetResultItemString(str, 1, pDepend, pDepend->GetBase());
  800. pCtrl->SetItemText(iItem, 1, str);
  801. //
  802. // Suggested item text.
  803. //
  804. GetResultItemString(str, 1, pDepend, m_aFailedList[i]->dwSuggested);
  805. pCtrl->SetItemText(iItem, 2, str);
  806. }
  807. }
  808. }
  809. return TRUE; // return TRUE unless you set the focus to a control
  810. // EXCEPTION: OCX Property Pages should return FALSE
  811. }
  812. //+----------------------------------------------------------------------------------
  813. // CDlgDependencyWarn::GetResultItemString
  814. //
  815. // Queries the result item for the full text it would display in the specifide
  816. // column if [dwValue] were it's base value.
  817. //
  818. // Arguments: [str] - The returned string
  819. // [iCol] - The column being queryed.
  820. // [pResult]- The result being queryed
  821. // [dwValue]- The base value to set before quering string. The old value
  822. // is not erased.
  823. //
  824. // Returns: TRUE - [str] is a valid string.
  825. // FALSE - something went wrong.
  826. //-----------------------------------------------------------------------------------
  827. BOOL
  828. CDlgDependencyWarn::GetResultItemString(
  829. CString &str,
  830. int iCol,
  831. CResult *pResult,
  832. LONG_PTR dwValue
  833. )
  834. {
  835. if(!pResult){
  836. return FALSE;
  837. }
  838. CFolder *pFolder = reinterpret_cast<CFolder *>(pResult->GetCookie());
  839. if(!pFolder){
  840. return FALSE;
  841. }
  842. //
  843. // Remember the old status and base.
  844. int iStatus = pResult->GetStatus();
  845. LONG_PTR lpData = pResult->GetBase();
  846. //
  847. // Set the base value to the new one, and status to not configured.
  848. //
  849. pResult->SetBase( dwValue );
  850. pResult->SetStatus(SCE_STATUS_NOT_CONFIGURED);
  851. //
  852. // Query for the string.
  853. //
  854. pResult->GetDisplayName( NULL, str, iCol );
  855. //
  856. // Reset the old status and base.
  857. //
  858. pResult->SetStatus( iStatus );
  859. pResult->SetBase(lpData);
  860. return TRUE;
  861. }