home *** CD-ROM | disk | FTP | other *** search
/ Clickx 47 / Clickx 47.iso / assets / software / sswitchxp152.exe / source / SpeedswitchXP / speedswitch.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-07-12  |  20.3 KB  |  633 lines

  1. /*
  2.    SpeedswitchXP V1.5
  3.    - Windows XP CPU Frequency Control for Notebooks -
  4.  
  5.    Copyright(c) 2002-2005 Christian Diefer
  6.  
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License version 2 as 
  9.    published by the Free Software Foundation.
  10.    
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.    
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20.  
  21. #define _UNICODE
  22.  
  23. #include <stdafx.h>
  24.  
  25. #include "TOptions.h"
  26. #include "speedswitch.h"
  27. #include <stdio.h>
  28. #include "SpeedswitchXP.h"
  29.  
  30. #define PROFILENAME "Speedswitch Control"
  31.  
  32. static BOOL comparePowerProfile( POWER_POLICY& pol1, POWER_POLICY& pol2 );
  33. static BOOL compareCPUScheme( MACHINE_PROCESSOR_POWER_POLICY& pol1, MACHINE_PROCESSOR_POWER_POLICY& pol2 );
  34. static BOOL comparePowerActionPolicy( POWER_ACTION_POLICY& pol1, POWER_ACTION_POLICY& pol2 );
  35. static BOOL compareCPUPowerPolicy( PROCESSOR_POWER_POLICY& pol1, PROCESSOR_POWER_POLICY& pol2 );
  36. static BOOL compareCPUPowerPolicyInfo( PROCESSOR_POWER_POLICY_INFO& pol1, PROCESSOR_POWER_POLICY_INFO& pol2 );
  37.  
  38. BOOLEAN __stdcall powerSchemeCallback(
  39.   UINT uiIndex,      // power scheme index
  40.   DWORD dwName,      // size of the sName string, in bytes
  41.   LPTSTR sName,      // name of the power scheme
  42.   DWORD dwDesc,      // size of the sDesc string, in bytes
  43.   LPTSTR sDesc,      // description string
  44.   PPOWER_POLICY pp,  // receives the power policy
  45.   LPARAM lParam      // user-defined value
  46. );
  47.  
  48. static TCHAR msg[2048];
  49. static TCHAR dummy[256];
  50. static UINT internalProfile;                  // the no of our own profile
  51. static UINT lastChecked;
  52. static POWER_POLICY toBeCopied;
  53.  
  54. int acThrottle;
  55. int dcThrottle;
  56. POWER_POLICY internalPolicy;           // our own profile policy
  57. MACHINE_PROCESSOR_POWER_POLICY mach;   // our own cpu policy
  58.  
  59. //------------------------------------------------------------------
  60. // Detect our own profile no
  61. //
  62. // return codes:
  63. //   -1: profile enumeration failed
  64. //   -2: profile not found (profile creation necessary)
  65. //   -3: CPU policy reading from our own profile failed
  66. //   -4: new profile activation failed
  67. //   >=0: profile no (success)
  68. //------------------------------------------------------------------
  69. int detectProfile()
  70. {
  71.   internalProfile = 0xffffffff;
  72.   lastChecked = 0xffffffff;
  73.  
  74.   if( !EnumPwrSchemes(&powerSchemeCallback,0) )
  75.     return -1;      // enumeration failed
  76.  
  77.   if( internalProfile == 0xffffffff )
  78.     return -2;      // profile not found
  79.  
  80.   // read the current CPU policy from our profile
  81.   if( !ReadProcessorPwrScheme(internalProfile,&mach) )
  82.     return -3;      // CPU policy reading failed
  83.  
  84.   if( !SetActivePwrScheme(internalProfile,NULL,NULL) )
  85.     return -4;  
  86.  
  87.   updateStates();
  88.  
  89.   return internalProfile;   // profile found, return profile no
  90. }
  91.  
  92. //------------------------------------------------------------------
  93. // create new profile from current one
  94. //
  95. // return codes:
  96. //   -1: active profile detection failed
  97. //   -2: reading active profile policy failed
  98. //   -3: writing our own profile failed
  99. //   -4: reading active cpu policy failed
  100. //   -5: writing our own cpu policy failed
  101. //   -6: new profile activation failed
  102. //   0: profile creation successful
  103. //------------------------------------------------------------------
  104. int createProfile()
  105. {
  106.   // get the # of the currently active profile
  107.   UINT activeProfile;
  108.   if( !GetActivePwrScheme(&activeProfile) )
  109.     return -1;  
  110.  
  111.   // read the profile policy settings
  112.   if( !ReadPwrScheme(activeProfile,&toBeCopied) )
  113.     return -2;
  114.  
  115.   // copy this to the one we use later
  116.   internalPolicy = toBeCopied;
  117.  
  118.   // create the # of our own profile
  119.   lastChecked++;
  120.  
  121.   // disable throttling in this new profile
  122.   internalPolicy.user.ForcedThrottleAc = 100;
  123.   internalPolicy.user.ForcedThrottleDc = 100;
  124.  
  125.   // write our own profile policy settings to the registry
  126.   if( !WritePwrScheme(&lastChecked,L"Speedswitch Control",L"\0\0",&internalPolicy) )
  127.     return -3;
  128.  
  129.   // this is our profile #
  130.   internalProfile = lastChecked;
  131.  
  132.   // read the CPU policy from the active profile
  133.   if( !ReadProcessorPwrScheme(activeProfile,&mach) )
  134.     return -4;
  135.  
  136.   // use this CPU policy for our own profile
  137.   if( !WriteProcessorPwrScheme(internalProfile,&mach) )
  138.     return -5;
  139.  
  140.   if( !SetActivePwrScheme(internalProfile,NULL,NULL) )
  141.     return -6;
  142.  
  143.   updateStates();
  144.  
  145.   return 0;
  146. }
  147.  
  148. //------------------------------------------------------------------
  149. // Callback function for power profile policy enumeration
  150. //------------------------------------------------------------------
  151. BOOLEAN __stdcall powerSchemeCallback(
  152.   UINT uiIndex,      // power scheme index
  153.   DWORD dwName,      // size of the sName string, in bytes
  154.   LPTSTR sName,      // name of the power scheme
  155.   DWORD dwDesc,      // size of the sDesc string, in bytes
  156.   LPTSTR sDesc,      // description string
  157.   PPOWER_POLICY pp,  // receives the power policy
  158.   LPARAM lParam      // user-defined value
  159. )
  160. {
  161.   lastChecked = uiIndex;
  162.  
  163.   CString s1;
  164.   s1.LoadStringW( IDS_SW24 );
  165.   wsprintf( &msg[_tcslen(msg)], s1, sName, uiIndex );
  166.   if( !_tcsicmp(dummy,_T(PROFILENAME)) )
  167.   {
  168.     internalProfile = uiIndex;
  169.     internalPolicy = *pp;
  170.     return FALSE;
  171.   }
  172.   
  173.   return TRUE;
  174. }
  175.  
  176. //------------------------------------------------------------------
  177. // get current ac/dc throttle from cpu policy
  178. //------------------------------------------------------------------
  179. void updateStates()
  180. {
  181.   acThrottle = mach.ProcessorPolicyAc.DynamicThrottle;
  182.   dcThrottle = mach.ProcessorPolicyDc.DynamicThrottle;
  183. }
  184.  
  185. //------------------------------------------------------------------
  186. // set current ac/dc throttle and activate that
  187. //------------------------------------------------------------------
  188. BOOL setState( BOOL ac, BYTE policy )
  189. {
  190.   checkProfile( 1 );
  191.  
  192.   if( ac )
  193.   {
  194.     acThrottle = policy;
  195.     mach.ProcessorPolicyAc.DynamicThrottle = policy;
  196.   }
  197.   else
  198.   {
  199.     dcThrottle = policy;
  200.     mach.ProcessorPolicyDc.DynamicThrottle = policy;
  201.   }
  202.  
  203.   if( !WriteProcessorPwrScheme(internalProfile,&mach) )
  204.     return FALSE;
  205.  
  206.   if( !SetActivePwrScheme(internalProfile,NULL,NULL) )
  207.     return FALSE;  
  208.  
  209.   return TRUE;
  210. }
  211.  
  212. //------------------------------------------------------------------
  213. // convert unicode string to ansi string
  214. //------------------------------------------------------------------
  215. char* uc2char( char* dest, void* s )
  216. {
  217.   char* t = (char*)s;
  218.   int i=-1;
  219.   int j=-1;
  220.   
  221.   do {
  222.     dest[++i] = t[++j];
  223.     t++;
  224.   } while( dest[i] );
  225.   
  226.   return dest;      
  227. }
  228.  
  229. //------------------------------------------------------------------
  230. // convert ansi string to unicode string
  231. //------------------------------------------------------------------
  232. char* char2uc( char* dest, char* s )
  233. {
  234.   char* t = (char*)s;
  235.   int i=-1;
  236.   int j=-1;
  237.   
  238.   do {
  239.     dest[++i] = t[++j];
  240.     dest[++i] = '\0';
  241.   } while( t[j] );
  242.   
  243.   return dest;      
  244. }
  245.  
  246. //------------------------------------------------------------------
  247. // convert CPU policy setting to string
  248. //------------------------------------------------------------------
  249. CString throttleString( UCHAR throttle )
  250. {
  251.   static CString s1, s2, s3, s4, s5;
  252.   static boolean init = false;
  253.  
  254.   if( !init )
  255.   {
  256.     s1.LoadStringW( IDS_MAIN56 );
  257.     s2.LoadStringW( IDS_MAIN57 );
  258.     s3.LoadStringW( IDS_MAIN58 );
  259.     s4.LoadStringW( IDS_MAIN59 );
  260.     s5.LoadStringW( IDS_SW7 );
  261.     init = true;
  262.   }
  263.  
  264.   switch( throttle )
  265.   {
  266.     case PO_THROTTLE_NONE:      return s1;
  267.     case PO_THROTTLE_CONSTANT:  return s2;
  268.     case PO_THROTTLE_DEGRADE:   return s3;
  269.     case PO_THROTTLE_ADAPTIVE:  return s4;
  270.   }
  271.   
  272.   return s5;    
  273. }
  274.  
  275. //------------------------------------------------------------------
  276. // power state to string
  277. //------------------------------------------------------------------
  278. CString sysPwrState( SYSTEM_POWER_STATE state )
  279. {
  280.   static CString s1, s2, s3, s4, s5, s6, s7, s8, s9;
  281.   static boolean init = false;
  282.  
  283.   if( !init )
  284.   {
  285.     s1.LoadStringW( IDS_SW8 );
  286.     s2.LoadStringW( IDS_SW9 );
  287.     s3.LoadStringW( IDS_SW10 );
  288.     s4.LoadStringW( IDS_SW11 );
  289.     s5.LoadStringW( IDS_SW12 );
  290.     s6.LoadStringW( IDS_SW13 );
  291.     s7.LoadStringW( IDS_SW14 );
  292.     s8.LoadStringW( IDS_SW15 );
  293.     s9.LoadStringW( IDS_SW7 );
  294.     init = true;
  295.   }
  296.  
  297.   switch( state )
  298.   {
  299.     case PowerSystemUnspecified: return s1; //_T("No wake up when lid opened");
  300.     case PowerSystemWorking:     return s2; //_T("S0");
  301.     case PowerSystemSleeping1:   return s3; //_T("S1");
  302.     case PowerSystemSleeping2:   return s4; //_T("S2");
  303.     case PowerSystemSleeping3:   return s5; //_T("S3");
  304.     case PowerSystemHibernate:   return s6; //_T("S4 (Hibernate)");
  305.     case PowerSystemShutdown:    return s7; //_T("S5 (Off)");
  306.     case PowerSystemMaximum:     return s8; //_T("???");
  307.   }
  308.     
  309.   return s9; //_T("(UNKNOWN)");
  310. }
  311.  
  312. //------------------------------------------------------------------
  313. // power action to string
  314. //------------------------------------------------------------------
  315. CString pwrAction( POWER_ACTION action )
  316. {
  317.   static CString s1, s2, s3, s4, s5, s6, s7, s8, s9;
  318.   static boolean init = false;
  319.  
  320.   if( !init )
  321.   {
  322.     s1.LoadStringW( IDS_SW16 );
  323.     s2.LoadStringW( IDS_SW17 );
  324.     s3.LoadStringW( IDS_SW18 );
  325.     s4.LoadStringW( IDS_SW19 );
  326.     s5.LoadStringW( IDS_SW20 );
  327.     s6.LoadStringW( IDS_SW21 );
  328.     s7.LoadStringW( IDS_SW22 );
  329.     s8.LoadStringW( IDS_SW23 );
  330.     s9.LoadStringW( IDS_SW7 );
  331.     init = true;
  332.   }
  333.  
  334.   switch( action )
  335.   {
  336.     case PowerActionNone:          return s1; //_T("No action");
  337.     case PowerActionReserved:      return s2; //_T("(reserved setting)");
  338.     case PowerActionSleep:         return s3; //_T("Sleep");
  339.     case PowerActionHibernate:     return s4; //_T("Hibernate");
  340.     case PowerActionShutdown:      return s5; //_T("Shutdown");
  341.     case PowerActionShutdownReset: return s6; //_T("Shutdown and reset");
  342.     case PowerActionShutdownOff:   return s7; //_T("Shutdown and power off");
  343.     case PowerActionWarmEject:     return s8; //_T("Warm eject");
  344.   }
  345.     
  346.   return s9; //_T("(UNKNOWN)");
  347. }
  348.  
  349. //------------------------------------------------------------------
  350. // get CPU usage on NT-style operating systems
  351. //------------------------------------------------------------------
  352. DWORD cpuUsageNT()
  353. {
  354.   static SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
  355.   static SYSTEM_TIME_INFORMATION SysTimeInfo;
  356.   static SYSTEM_BASIC_INFORMATION SysBaseInfo;
  357.   static double dbIdleTime;
  358.   static double dbSystemTime;
  359.   static LONG status;
  360.   static LARGE_INTEGER liOldIdleTime = {0,0};
  361.   static LARGE_INTEGER liOldSystemTime = {0,0};
  362.   static BOOL init = FALSE;
  363.   static PROCNTQSI NtQuerySystemInformation = NULL;
  364.   DWORD retVal = 0xffffffff;
  365.  
  366.   if( !init )
  367.   {
  368.     NtQuerySystemInformation = (PROCNTQSI)GetProcAddress( GetModuleHandle(_T("ntdll")), "NtQuerySystemInformation" );
  369.  
  370.     if( !NtQuerySystemInformation )
  371.       return 0xffffffff;
  372.  
  373.     // get number of processors in the system
  374.     status = NtQuerySystemInformation( SystemBasicInformation, &SysBaseInfo, sizeof(SysBaseInfo), NULL );
  375.     if( status != NO_ERROR )
  376.       return 0xffffffff;
  377.  
  378.     init = TRUE;
  379.   }
  380.  
  381.   // get new system time
  382.   status = NtQuerySystemInformation( SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0 );
  383.  
  384.   if( status != NO_ERROR )
  385.     return 0xffffffff;
  386.  
  387.   // get new CPU's idle time
  388.   status = NtQuerySystemInformation( SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL );
  389.   if( status != NO_ERROR )
  390.     return 0xffffffff;
  391.  
  392.   // if it's a first call - skip it
  393.   if( liOldIdleTime.QuadPart != 0 )
  394.   {
  395.     // CurrentValue = NewValue - OldValue
  396.     dbIdleTime = Li2Double( SysPerfInfo.liIdleTime ) - Li2Double( liOldIdleTime );
  397.     dbSystemTime = Li2Double( SysTimeInfo.liKeSystemTime ) - Li2Double( liOldSystemTime );
  398.  
  399.     // CurrentCpuIdle = IdleTime / SystemTime
  400.     dbIdleTime = dbIdleTime / dbSystemTime;
  401.  
  402.     // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
  403.     dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5;
  404.     
  405.     retVal = (DWORD)dbIdleTime;
  406.   }
  407.  
  408.   // store new CPU's idle and system time
  409.   liOldIdleTime = SysPerfInfo.liIdleTime;
  410.   liOldSystemTime = SysTimeInfo.liKeSystemTime;
  411.  
  412.   return retVal;
  413. }
  414.  
  415. //------------------------------------------------------------------
  416. // write changed power policies
  417. //
  418. // return codes:
  419. //   -1: power policy writing failure
  420. //   -2: cpu policy writing failure
  421. //   0: success
  422. //------------------------------------------------------------------
  423. int writePolicies( BOOL power, BOOL cpu )
  424. {
  425.   if( power && !WritePwrScheme(&internalProfile,L"Speedswitch Control",L"\0\0",&internalPolicy) )
  426.   {
  427.     ReadPwrScheme( internalProfile, &internalPolicy );
  428.     return -1;
  429.   }
  430.  
  431.   if( cpu && !WriteProcessorPwrScheme(internalProfile,&mach) )
  432.   {
  433.     ReadProcessorPwrScheme( internalProfile, &mach );
  434.  
  435.     if( power )
  436.       SetActivePwrScheme( internalProfile, NULL, NULL );
  437.  
  438.     return -2;
  439.   }
  440.  
  441.   SetActivePwrScheme( internalProfile, NULL, NULL );
  442.   return 0;
  443. }
  444.  
  445. //------------------------------------------------------------------
  446. // check power scheme integrity
  447. //
  448. // check: 0=no consistency check
  449. //        1=check power scheme only
  450. //        2=check processor scheme only
  451. //        3=check both power and processor scheme
  452. //------------------------------------------------------------------
  453. BOOL checkProfile( int check )
  454. {
  455.   log( _T("Checking power scheme integrity ...") );
  456.   
  457.   CString err;
  458.   err.LoadStringW( IDS_MAINERR2 );
  459.  
  460.   POWER_POLICY policyTemp;
  461.   MACHINE_PROCESSOR_POWER_POLICY machTemp;
  462.   static TCHAR msg[1024];   // fⁿr diverse Fehlertexte
  463.   BOOL forceActivate = FALSE;
  464.  
  465.   if( !ReadPwrScheme(internalProfile,&policyTemp) )
  466.   {
  467.     log( _T("Recreating power scheme ...") );
  468.     UINT x = internalProfile;
  469.  
  470.     if( !WritePwrScheme(&x,L"Speedswitch Control",L"\0\0",&internalPolicy) )
  471.     {
  472.       CString s1;
  473.       s1.LoadStringW( IDS_SW1 );
  474.       wsprintf( msg, s1, GetLastError() );
  475.       MessageBox( NULL, msg, err, MB_ICONEXCLAMATION|MB_OK );
  476.       return FALSE;
  477.     }
  478.  
  479.     forceActivate = TRUE;
  480.   }
  481.   else if( check&1 )
  482.   {
  483.     if( !comparePowerProfile(policyTemp,internalPolicy) )
  484.     {
  485.       log( _T("Restoring power scheme data ...") );
  486.       UINT x = internalProfile;
  487.  
  488.       if( !WritePwrScheme(&x,L"Speedswitch Control",L"\0\0",&internalPolicy) )
  489.       {
  490.         CString s1;
  491.         s1.LoadStringW( IDS_SW2 );
  492.         wsprintf( msg, s1, GetLastError() );
  493.         MessageBox( NULL, msg, err, MB_ICONEXCLAMATION|MB_OK );
  494.         return FALSE;
  495.       }
  496.  
  497.       forceActivate = TRUE;
  498.     }
  499.   }
  500.  
  501.   if( !ReadProcessorPwrScheme(internalProfile,&machTemp) )
  502.   {
  503.     log( _T("Recreating processor scheme ...") );
  504.     if( !WriteProcessorPwrScheme(internalProfile,&mach) )
  505.     {
  506.       CString s1;
  507.       s1.LoadStringW( IDS_SW3 );
  508.       wsprintf( msg, s1, GetLastError() );
  509.       MessageBox( NULL, msg, err, MB_ICONEXCLAMATION|MB_OK );
  510.       return FALSE;
  511.     }   
  512.  
  513.     forceActivate = TRUE;
  514.   }
  515.   else if( check&2 )
  516.   {
  517.     if( !compareCPUScheme(machTemp,mach) )
  518.     {
  519.       log( _T("Restoring processor scheme data ...") );
  520.       if( !WriteProcessorPwrScheme(internalProfile,&mach) )
  521.       {
  522.         CString s1;
  523.         s1.LoadStringW( IDS_SW4 );
  524.         wsprintf( msg, s1, GetLastError() );
  525.         MessageBox( NULL, msg, err, MB_ICONEXCLAMATION|MB_OK );
  526.         return FALSE;
  527.       }  
  528.  
  529.       forceActivate = TRUE;
  530.     }
  531.   }
  532.  
  533.   UINT profile;
  534.  
  535.   if( !GetActivePwrScheme(&profile) )
  536.   {
  537.     CString s1;
  538.     s1.LoadStringW( IDS_SW5 );
  539.     wsprintf( msg, s1, GetLastError() );
  540.     MessageBox( NULL, msg, err, MB_OK|MB_ICONEXCLAMATION );
  541.     return FALSE;
  542.   }
  543.  
  544.   if( forceActivate || profile!=internalProfile )
  545.   {
  546.     log( _T("Reactivating power scheme (%d, %d) ..."), profile, internalProfile );
  547.     if( !SetActivePwrScheme(internalProfile,NULL,NULL) )
  548.     {
  549.       CString s1;
  550.       s1.LoadStringW( IDS_SW6 );
  551.       wsprintf( msg, s1, GetLastError() );
  552.       MessageBox( NULL, msg, err, MB_ICONEXCLAMATION|MB_OK );
  553.       return FALSE;
  554.     }
  555.   }
  556.  
  557.   return TRUE;
  558. }
  559.  
  560. static BOOL comparePowerProfile( POWER_POLICY& pol1, POWER_POLICY& pol2 )
  561. {
  562.   return pol1.user.Revision == pol2.user.Revision
  563.     &&   comparePowerActionPolicy(pol1.user.IdleAc,pol2.user.IdleAc)
  564.     &&   comparePowerActionPolicy(pol1.user.IdleDc,pol2.user.IdleDc)
  565.     &&   pol1.user.IdleTimeoutAc == pol2.user.IdleTimeoutAc
  566.     &&   pol1.user.IdleTimeoutDc == pol2.user.IdleTimeoutDc
  567.     &&   pol1.user.IdleSensitivityAc == pol2.user.IdleSensitivityAc
  568.     &&   pol1.user.IdleSensitivityDc == pol2.user.IdleSensitivityDc
  569.     &&   pol1.user.ThrottlePolicyAc == pol2.user.ThrottlePolicyAc
  570.     &&   pol1.user.ThrottlePolicyDc == pol2.user.ThrottlePolicyDc
  571.     &&   pol1.user.MaxSleepAc == pol2.user.MaxSleepAc
  572.     &&   pol1.user.MaxSleepDc == pol2.user.MaxSleepDc
  573.     &&   pol1.user.VideoTimeoutAc == pol2.user.VideoTimeoutAc
  574.     &&   pol1.user.VideoTimeoutDc == pol2.user.VideoTimeoutDc
  575.     &&   pol1.user.SpindownTimeoutAc == pol2.user.SpindownTimeoutAc
  576.     &&   pol1.user.SpindownTimeoutDc == pol2.user.SpindownTimeoutDc
  577.     &&   pol1.user.OptimizeForPowerAc == pol2.user.OptimizeForPowerAc
  578.     &&   pol1.user.OptimizeForPowerDc == pol2.user.OptimizeForPowerDc
  579.     &&   pol1.user.FanThrottleToleranceAc == pol2.user.FanThrottleToleranceAc
  580.     &&   pol1.user.FanThrottleToleranceDc == pol2.user.FanThrottleToleranceDc
  581.     &&   pol1.user.ForcedThrottleAc == pol2.user.ForcedThrottleAc
  582.     &&   pol1.user.ForcedThrottleDc == pol2.user.ForcedThrottleDc
  583.     &&   pol1.mach.Revision == pol2.mach.Revision
  584.     &&   pol1.mach.MinSleepAc == pol2.mach.MinSleepAc
  585.     &&   pol1.mach.MinSleepDc == pol2.mach.MinSleepDc
  586.     &&   pol1.mach.ReducedLatencySleepAc == pol2.mach.ReducedLatencySleepAc
  587.     &&   pol1.mach.ReducedLatencySleepDc == pol2.mach.ReducedLatencySleepDc
  588.     &&   pol1.mach.DozeTimeoutAc == pol2.mach.DozeTimeoutAc
  589.     &&   pol1.mach.DozeTimeoutDc == pol2.mach.DozeTimeoutDc
  590.     &&   pol1.mach.DozeS4TimeoutAc == pol2.mach.DozeS4TimeoutAc
  591.     &&   pol1.mach.DozeS4TimeoutDc == pol2.mach.DozeS4TimeoutDc
  592.     &&   pol1.mach.MinThrottleAc == pol2.mach.MinThrottleAc
  593.     &&   pol1.mach.MinThrottleDc == pol2.mach.MinThrottleDc
  594.     &&   comparePowerActionPolicy(pol1.mach.OverThrottledAc,pol2.mach.OverThrottledAc)
  595.     &&   comparePowerActionPolicy(pol1.mach.OverThrottledDc,pol2.mach.OverThrottledDc);
  596. }
  597.  
  598. static BOOL comparePowerActionPolicy( POWER_ACTION_POLICY& pol1, POWER_ACTION_POLICY& pol2 )
  599. {
  600.   return pol1.Action == pol2.Action
  601.     &&   pol1.EventCode == pol2.EventCode
  602.     &&   pol1.Flags == pol2.Flags;
  603. }
  604.  
  605. static BOOL compareCPUScheme( MACHINE_PROCESSOR_POWER_POLICY& pol1, MACHINE_PROCESSOR_POWER_POLICY& pol2 )
  606. {
  607.   return pol1.Revision == pol2.Revision
  608.     &&   compareCPUPowerPolicy(pol1.ProcessorPolicyAc,pol2.ProcessorPolicyAc)
  609.     &&   compareCPUPowerPolicy(pol1.ProcessorPolicyDc,pol2.ProcessorPolicyDc);
  610. }
  611.  
  612. static BOOL compareCPUPowerPolicy( PROCESSOR_POWER_POLICY& pol1, PROCESSOR_POWER_POLICY& pol2 )
  613. {
  614.   return pol1.Revision == pol2.Revision
  615.     &&   pol1.DynamicThrottle == pol2.DynamicThrottle
  616.     &&   pol1.PolicyCount == pol2.PolicyCount
  617.     &&   ((pol1.PolicyCount>0) ? compareCPUPowerPolicyInfo(pol1.Policy[0],pol2.Policy[0]) : TRUE)
  618.     &&   ((pol1.PolicyCount>1) ? compareCPUPowerPolicyInfo(pol1.Policy[1],pol2.Policy[1]) : TRUE)
  619.     &&   ((pol1.PolicyCount>2) ? compareCPUPowerPolicyInfo(pol1.Policy[2],pol2.Policy[2]) : TRUE);
  620. }
  621.  
  622. static BOOL compareCPUPowerPolicyInfo( PROCESSOR_POWER_POLICY_INFO& pol1, PROCESSOR_POWER_POLICY_INFO& pol2 )
  623. {
  624.   return pol1.TimeCheck == pol2.TimeCheck
  625.     &&   pol1.DemoteLimit == pol2.DemoteLimit
  626.     &&   pol1.PromoteLimit == pol2.PromoteLimit
  627.     &&   pol1.DemotePercent == pol2.DemotePercent
  628.     &&   pol1.PromotePercent == pol2.PromotePercent
  629.     &&   pol1.AllowDemotion == pol2.AllowDemotion
  630.     &&   pol1.AllowPromotion == pol2.AllowPromotion;
  631. }
  632.  
  633.