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

  1. /*
  2.    SpeedswitchXP V1.5
  3.    - Windows XP CPU Frequency Control for Notebooks -
  4.  
  5.    Copyright(c) 2002-2006 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. #include "SpeedswitchXP.h"
  25. #include "CPUData.h"
  26. #include "cpuid.h"
  27. #include "speed.h"
  28. #include "speedswitch.h"
  29. #include <ctype.h>
  30.  
  31. // CCPUData dialog
  32.  
  33. IMPLEMENT_DYNAMIC(CCPUData, CDialog)
  34. CCPUData::CCPUData(CWnd* pParent /*=NULL*/)
  35.     : CDialog(CCPUData::IDD, pParent)
  36.   , m_szSupportsCPUID(_T(""))
  37.   , m_szVendor(_T(""))
  38.   , m_szFeatures(_T(""))
  39.   , m_iMaxIDVal(0)
  40.   , m_szManufacturer(_T(""))
  41.   , m_iFamily(0)
  42.   , m_iModel(0)
  43.   , m_iStepping(0)
  44.   , m_iFType(0)
  45.   , m_szMaxExLevel(_T(""))
  46.   , m_szExCPUName(_T(""))
  47.   , m_szExFeatures(_T(""))
  48.   , m_iBrandID(0)
  49.   , m_szBrandStr(_T(""))
  50.   , m_szExFeatures2(_T(""))
  51.   , m_szFlags(_T(""))
  52.   , m_szCacheInfo(_T(""))
  53.   , m_szCoreType(_T(""))
  54.   , m_szStructureSize(_T(""))
  55. { }
  56.  
  57. CCPUData::~CCPUData()
  58. { }
  59.  
  60. void CCPUData::DoDataExchange(CDataExchange* pDX)
  61. {
  62.   CDialog::DoDataExchange(pDX);
  63.   DDX_Control(pDX, IDC_LIST2, m_cList);
  64. }
  65.  
  66. BEGIN_MESSAGE_MAP(CCPUData, CDialog)
  67. END_MESSAGE_MAP()
  68.  
  69. // CCPUData message handlers
  70.  
  71. BOOL CCPUData::OnInitDialog()
  72. {
  73.   CDialog::OnInitDialog();
  74.   
  75.   CRect rect;
  76.   m_cList.GetClientRect( &rect );
  77.   int nColInterval = rect.Width()/8;
  78.  
  79.   CString s1;
  80.   s1.LoadStringW( IDS_CPU1 );
  81.   m_cList.InsertColumn( 0, s1, LVCFMT_LEFT, nColInterval*2 );
  82.   s1.LoadStringW( IDS_CPU2 );
  83.   m_cList.InsertColumn( 1, s1, LVCFMT_LEFT, nColInterval*5+nColInterval/2 );
  84.  
  85.   s1.LoadStringW( IDS_CPU3 );
  86.   int nIndex = m_cList.InsertItem( 0, s1 );
  87.   m_cList.SetItemText( nIndex, 1, cpuStr );
  88.  
  89.   s1.LoadStringW( IDS_CPU4 );
  90.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  91.   m_cList.SetItemText( nIndex, 1, m_szManufacturer );
  92.  
  93.   s1.LoadStringW( IDS_CPU5 );
  94.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  95.   m_cList.SetItemText( nIndex, 1, vendorID );
  96.  
  97.   s1.LoadStringW( IDS_CPU6 );
  98.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  99.   m_cList.SetItemText( nIndex, 1, m_szCoreType );
  100.  
  101.   s1.LoadStringW( IDS_CPU7 );
  102.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  103.   m_cList.SetItemText( nIndex, 1, m_szStructureSize );
  104.  
  105.   if( cacheStrNo != 0 )
  106.   {
  107.     for( int i=0; i<cacheStrNo; i++ )
  108.     {
  109.       s1.LoadStringW( IDS_CPU8 );
  110.       nIndex = m_cList.InsertItem( nIndex+1, i==0 ? s1 : _T("") );
  111.       m_cList.SetItemText( nIndex, 1, cacheStr[i] );
  112.     }
  113.   }
  114.  
  115.   CString szFamily, szModel, szStepping, szType, szBrand, szMaxLevel;
  116.   szFamily.Format( _T("%d"), familyid );
  117.   szModel.Format( _T("%d"), modelid );
  118.   szStepping.Format( _T("%d"), steppingid );
  119.   szType.Format( _T("%d"), typid );
  120.   szBrand.Format( _T("%d"), brandID & 255 );
  121.   szMaxLevel.Format( _T("%d"), maxIDVal );
  122.  
  123.   nIndex = m_cList.InsertItem( nIndex+1, _T("") );
  124.   m_cList.SetItemText( nIndex, 1, _T("") );
  125.  
  126.   s1.LoadStringW( IDS_CPU9 );
  127.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  128.   m_cList.SetItemText( nIndex, 1, szFamily );
  129.  
  130.   s1.LoadStringW( IDS_CPU10 );
  131.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  132.   m_cList.SetItemText( nIndex, 1, szModel );
  133.  
  134.   s1.LoadStringW( IDS_CPU11 );
  135.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  136.   m_cList.SetItemText( nIndex, 1, szStepping );
  137.  
  138.   s1.LoadStringW( IDS_CPU12 );
  139.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  140.   m_cList.SetItemText( nIndex, 1, szType );
  141.  
  142.   s1.LoadStringW( IDS_CPU13 );
  143.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  144.   m_cList.SetItemText( nIndex, 1, szBrand );
  145.  
  146.   s1.LoadStringW( IDS_CPU14 );
  147.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  148.   m_cList.SetItemText( nIndex, 1, brandStr );
  149.  
  150.   s1.LoadStringW( IDS_CPU15 );
  151.   CString s2;
  152.   s2.LoadStringW( IDS_CPU16 );
  153.   m_szSupportsCPUID = (supportsCPUID ? s1 : s2);
  154.  
  155.   s1.LoadStringW( IDS_CPU17 );
  156.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  157.   m_cList.SetItemText( nIndex, 1, m_szSupportsCPUID );
  158.  
  159.   s1.LoadStringW( IDS_CPU18 );
  160.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  161.   m_cList.SetItemText( nIndex, 1, szMaxLevel );
  162.  
  163.   s1.LoadStringW( IDS_CPU19 );
  164.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  165.   m_cList.SetItemText( nIndex, 1, m_szMaxExLevel );
  166.  
  167.   s1.LoadStringW( IDS_CPU20 );
  168.   nIndex = m_cList.InsertItem( nIndex+1, s1 );
  169.   m_cList.SetItemText( nIndex, 1, m_szFeatures + _T("  ") + m_szExFeatures + _T("  ") + m_szExFeatures2 );
  170.  
  171.   s1.LoadStringW( IDS_CPU21 );
  172.  
  173.   if( flagNo != 0 )
  174.   {
  175.     nIndex = m_cList.InsertItem( nIndex+1, _T("") );
  176.     m_cList.SetItemText( nIndex, 1, _T("") );
  177.  
  178.     for( int i=0; i<flagNo; i++ )
  179.     {
  180.       nIndex = m_cList.InsertItem( nIndex+1, i==0 ? s1 : _T("") );
  181.       m_cList.SetItemText( nIndex, 1, flag[i] );
  182.     }
  183.   }
  184.  
  185.   UpdateData( FALSE );
  186.   return TRUE;
  187. }
  188.  
  189. void CCPUData::setVars()
  190. {
  191.   init();
  192.   getCPUType();
  193.  
  194.   m_szExCPUName = cpuStr;
  195.   m_szVendor = vendorID;
  196.   m_iFType = typid;
  197.   m_iFamily = familyid;
  198.   m_iModel = modelid;
  199.   m_iStepping = steppingid;
  200.   m_iMaxIDVal = maxIDVal;
  201.   m_iBrandID = brandID & 255;
  202.   m_szBrandStr = brandStr;
  203.  
  204.   if( coreType == NULL )
  205.     m_szCoreType = "?";
  206.   else
  207.     m_szCoreType = coreType;
  208.   
  209.   if( structureSize == NULL )
  210.     m_szStructureSize = "?";
  211.   else
  212.     m_szStructureSize = structureSize;
  213.  
  214.   CString s1;
  215.   s1.LoadStringW( IDS_CPU22 );
  216.  
  217.   if( supportsCPUID && maxIDVal>=2 )
  218.     readCacheInfo();
  219.   else if( cacheSize != NULL )
  220.     cacheStr[cacheStrNo++].Format( s1, cacheSize );
  221.  
  222.   m_szFeatures.Format( _T("0x%08x"), features );
  223.   m_szExFeatures.Format( _T("0x%08x"), exfeatures );
  224.   m_szExFeatures2.Format( _T("0x%08x"), exfeatures2 );
  225.  
  226.   if( exlevel >= 0x80000000 )
  227.     m_szMaxExLevel.Format( _T("0x%08x"), exlevel );
  228.   else
  229.     m_szMaxExLevel = _T("---");
  230.  
  231.   memset( &lf, 0, sizeof(LOGFONT) ); 
  232.  
  233.   *flagText = '\0';
  234.  
  235.   if( f_fpu )   Message( _T("FPU   - Floating Point Unit") );
  236.   if( f_vme )   Message( _T("VME   - V86 Mode Extensions") );
  237.   if( f_de )    Message( _T("DE    - Debug Extensions") );
  238.   if( f_pse )   Message( _T("PSE   - Page Size Extensions") );
  239.   if( f_tsc )   Message( _T("TSC   - Timestamp Counter") );
  240.   if( f_msr )   Message( _T("MSR   - Model Specific Registers") );
  241.   if( f_pae )   Message( _T("PAE   - Physical Address Extensions") );
  242.   if( f_mce )   Message( _T("MCE   - Machine Check Exception") );
  243.   if( f_c8x )   Message( _T("C8X   - CMPXCHG8B Instruction") );
  244.   if( f_apic )  Message( _T("APIC  - Local APIC") );
  245.   if( f_sep )   Message( _T("SEP   - Fast System Call") );
  246.   if( f_mtrr )  Message( _T("MTRR  - Memory Type Range Registers") );
  247.   if( f_pge )   Message( _T("PGE   - Page Global Enable") );
  248.   if( f_mca )   Message( _T("MCA   - Machine Check Architecture") );
  249.   if( f_cmov )  Message( _T("CMOV  - CMOV Instructions") );
  250.   if( f_pse36 ) Message( _T("PSE36 - 36bit Page Size Extensions") );
  251.   if( f_psn )   Message( _T("PSN   - Processor Serial Number") );
  252.   if( f_mmx )   Message( _T("MMX   - MMX Instructions") );
  253.  
  254.   switch( vendor )
  255.   {
  256.     case 0: m_szManufacturer = _T("Intel");
  257.             if( f_acpi ) Message( _T("ACPI  - ACPI Support") );
  258.             if( f_pat )  Message( _T("PAT   - Page Attribute Table") );
  259.             if( f_fxsr ) Message( _T("FXSR  - FXSAVE/FXRSTOR Instructions") );
  260.             if( f_sse )  Message( _T("SSE   - SSE Instructions") );
  261.             if( f_sse2 ) Message( _T("SSE2  - SSE2 Instructions") );
  262.             if( f_ss )   Message( _T("SS    - Self Snoop") );
  263.             if( f_htt )  Message( _T("HTMC  - Hyperthreading/Multicore Technology") );
  264.             if( f_tm1 )  Message( _T("TM1   - Thermal Monitor 1") );
  265.             if( f_pbe )  Message( _T("PBE   - Pending Break Enable") );
  266.             if( f_ia64 ) Message( _T("IA64  - IA64 Instructions") );
  267.             if( f_sse3 ) Message( _T("SSE3  - SSE3 Instructions") );
  268.             if( f_mon )  Message( _T("MMW   - MONITOR/MWAIT") );
  269.             if( f_cpl )  Message( _T("CPL   - CPL Qualified Debug Store") );
  270.             if( f_vmx )  Message( _T("VMX   - Virtual Machine Extensions") );
  271.             if( f_est )  Message( _T("EST   - Enhanced Intel Speed Step") );
  272.             if( f_tm2 )  Message( _T("TM2   - Thermal Monitor 2") );
  273.             if( f_l1id ) Message( _T("L1ID  - L1 Context ID") );
  274.             if( f_c16b ) Message( _T("C16X  - CMPXCHG16B Support") );
  275.             //if( f_xtpr ) Message( _T("XTPR  - xTPR Disable") );
  276.             break;
  277.  
  278.     case 1: m_szManufacturer = _T("AMD");
  279.             if( f_fsc )      Message( _T("FSC   - Fast System Call") );
  280.             if( f_fcmov )    Message( _T("FCMOV - FCMOV Instruction") );
  281.             if( f_mmxext )   Message( _T("MMXE  - Extended MMX Instructions") );
  282.             if( f_sse )      Message( _T("SSE   - SSE Instructions") );
  283.             if( f_sse2 )     Message( _T("SSE2  - SSE2 Instructions") );
  284.             if( f_3dnowext ) Message( _T("3DNE  - Extended 3DNow! Instructions") );
  285.             if( f_3dnow )    Message( _T("3DNOW - 3DNow! Instructions") );
  286.             break;
  287.  
  288.     case 2: m_szManufacturer = _T("Cyrix");
  289.             if( f_cxmmx ) Message( _T("CXMMX - Cyrix MMX Instructions") );
  290.             break;
  291.  
  292.     case 3: m_szManufacturer = _T("Transmeta");
  293.             break;
  294.  
  295.     case 4: m_szManufacturer = _T("Centaur");
  296.             if( f_3dnow ) Message( _T("3DNOW - 3DNow! Instructions") );
  297.             break;
  298.  
  299.     case 5: m_szManufacturer = _T("Rise");
  300.             break;
  301.  
  302.     case 6: m_szManufacturer = _T("UMC");
  303.             break;
  304.  
  305.     case 7: m_szManufacturer = _T("NexGen");
  306.             break;
  307.  
  308.     default:m_szManufacturer = _T("Unknown");
  309.             break;
  310.   }
  311.  
  312.   m_szFlags = flagText;
  313. }
  314.  
  315. void CCPUData::getCPUType()
  316. {
  317.   cpuType = wincpuid();
  318.   supportsCPUID = wincpuidsupport();
  319.  
  320.   switch( cpuType & (CLONE_MASK-1) )
  321.   {
  322.     case 0: _tcscpy_s( cpuStr, _T("8086") );
  323.             break;
  324.  
  325.     case 1: _tcscpy_s( cpuStr, _T("80186") );
  326.             break;
  327.  
  328.     case 2: _tcscpy_s( cpuStr, _T("80286") );
  329.             break;
  330.  
  331.     case 3: _tcscpy_s( cpuStr, _T("80386") );
  332.             break;
  333.  
  334.     case 4: _tcscpy_s( cpuStr, _T("80486") );
  335.             break;
  336.  
  337.     case 5: _tcscpy_s( cpuStr, _T("Pentium") );
  338.             break;
  339.  
  340.     case 6: _tcscpy_s( cpuStr, _T("Pentium Pro") );
  341.             break;
  342.  
  343.     case 15:_tcscpy_s( cpuStr, _T("Pentium 4") );
  344.             break;
  345.  
  346.     default:_tcscpy_s( cpuStr, _T("Unknown") );
  347.             break;
  348.   }
  349.  
  350.   familyid = cpuType & (CLONE_MASK-1);
  351.  
  352.   if( !supportsCPUID )
  353.     return;
  354.  
  355.   getCPUFeatures();
  356.  
  357.   typid = (family & (3<<12))>>12;
  358.   familyid = (family&(15<<8))>>8;
  359.   modelid = (family&(15<<4))>>4;
  360.   steppingid = family&15;
  361.  
  362.   f_fpu = features & 1;
  363.   f_vme = features & 2;
  364.   f_de = features & 4;
  365.   f_pse = features & 8;
  366.   f_tsc = features & 16;
  367.   f_msr = features & 32;
  368.   f_pae = features & 64;
  369.   f_mce = features & 128;
  370.   f_c8x = features & (1<<8);
  371.   f_apic = features & (1<<9);
  372.   f_sep = features & (1<<11);
  373.   f_mtrr = features & (1<<12);
  374.   f_pge = features & 8192;
  375.   f_mca = features & 16384;
  376.   f_cmov = features & 32768;
  377.   f_pse36 = features & (1<<17);
  378.   f_psn = features & (1<<18);
  379.   f_mmx = features & (1<<23);
  380.  
  381.   if( !_tcsicmp(vendorID,_T("GenuineIntel")) )
  382.   {
  383.     vendor = 0;   // Intel
  384.     f_pat = features & (1<<16);
  385.     f_acpi = features & (1<<22);
  386.     f_fxsr = features & (1<<24);
  387.     f_sse = features & (1<<25);
  388.     f_sse2 = features & (1<<26);
  389.     f_ss = features & (1<<27);
  390.     f_htt = features & (1<<28);
  391.     f_tm1 = features & (1<<29);
  392.     f_ia64 = features & (1<<30);
  393.     f_pbe = features & (1<<31);
  394.     f_sse3 = exfeatures & 1;
  395.     f_mon = exfeatures & (1<<3);
  396.     f_cpl = exfeatures & (1<<4);
  397.     f_vmx = exfeatures & (1<<5);
  398.     f_est = exfeatures & (1<<7);
  399.     f_tm2 = exfeatures & (1<<8);
  400.     f_l1id = exfeatures & (1<<10);
  401.     f_c16b = exfeatures & (1<<13);
  402.     identifyIntel();
  403.   }
  404.   else if( !_tcsicmp(vendorID,_T("AuthenticAMD")) )
  405.   {
  406.     vendor = 1;   // AMD
  407.     f_fsc = features & (1<<10);
  408.     f_fcmov = features & (1<<16);
  409.     f_mmxext = features & (1<<22);
  410.     f_sse = features & (1<<25);
  411.     f_sse2 = features & (1<<26);
  412. //    f_3dnowext = features & (1<<30);
  413. //    f_3dnow = features & (1<<31);
  414.     identifyAMD();
  415.   }
  416.   else if( !_tcsicmp(vendorID,_T("CyrixInstead")) )
  417.   {
  418.     vendor = 2;   // Cyrix
  419.     f_cxmmx = features & (1<<24);
  420.   }
  421.   else if( !_tcsicmp(vendorID,_T("GenuineTMx86")) )
  422.   {
  423.     vendor = 3;   // Transmeta
  424.   }
  425.   else if( !_tcsicmp(vendorID,_T("CentaurHauls")) )
  426.   {
  427.     vendor = 4;   // Centaur
  428.     f_3dnow = features & (1<<31);
  429.   }
  430.   else if( !_tcsicmp(vendorID,_T("RISERISERISE")) )
  431.   {
  432.     vendor = 5;   // Rise
  433.   }
  434.   else if( !_tcsicmp(vendorID,_T("UMC UMC UMC ")) )
  435.   {
  436.     vendor = 6;   // UMC
  437.   }
  438.   else if( !_tcsicmp(vendorID,_T("NexGenDriven")) )
  439.   {
  440.     vendor = 7;   // NexGen
  441.   }
  442.  
  443.   DWORD exl;
  444.  
  445.   __asm {
  446.     pushad
  447.     mov eax,0x80000000
  448.     CPU_ID
  449.     mov dword ptr exl,eax
  450.     popad
  451.   }
  452.  
  453.   exlevel = exl;
  454.  
  455.   if( exlevel>=0x80000001 && vendor==1 )  // nur bei AMD
  456.   {
  457.     DWORD amdflags;
  458.  
  459.     __asm {
  460.       pushad
  461.       mov eax, 0x80000001
  462.       CPU_ID
  463.       mov dword ptr amdflags, edx
  464.       popad
  465.     }
  466.  
  467.     exfeatures2 = amdflags;
  468.  
  469.     f_3dnow = amdflags & (1<<31);
  470.     f_3dnowext = amdflags & (1<<30);
  471.   }
  472.  
  473.   if( exlevel >= 0x80000004 )
  474.   {
  475.     DWORD pstr[12];
  476.  
  477.     __asm {
  478.       pushad
  479.       mov eax, 0x80000002
  480.       CPU_ID
  481.       mov dword ptr pstr, eax
  482.       mov dword ptr pstr+4, ebx
  483.       mov dword ptr pstr+8, ecx
  484.       mov dword ptr pstr+12, edx
  485.       mov eax, 0x80000003
  486.       CPU_ID
  487.       mov dword ptr pstr+16, eax
  488.       mov dword ptr pstr+20, ebx
  489.       mov dword ptr pstr+24, ecx
  490.       mov dword ptr pstr+28, edx
  491.       mov eax, 0x80000004
  492.       CPU_ID
  493.       mov dword ptr pstr+32, eax
  494.       mov dword ptr pstr+36, ebx
  495.       mov dword ptr pstr+40, ecx
  496.       mov dword ptr pstr+44, edx
  497.       popad
  498.     }
  499.  
  500.     char* s = (char*)pstr;
  501.     while( *s && isspace(*s) )
  502.       s++;
  503.  
  504. #ifdef _UNICODE
  505.     wchar_t pstrw[48];
  506.     char2uc( (char*)pstrw, s );
  507.     _tcscpy_s( cpuStr, pstrw );
  508. #else
  509.     strcpy_s( cpuStr, s );
  510. #endif
  511.   }
  512. }
  513.  
  514. void CCPUData::identifyIntel()
  515. {
  516.   boolean noFamily = false;
  517.   TCHAR* cpuString = NULL;
  518.  
  519.   switch( familyid )
  520.   {
  521.     case 4: switch( modelid )
  522.             {
  523.               case 0: cpuString = _T("80486DX-25/33");
  524.                       break;
  525.  
  526.               case 1: cpuString = _T("80486DX-50");
  527.                       break;
  528.  
  529.               case 2: cpuString = _T("80486SX");
  530.                       break;
  531.  
  532.               case 3: cpuString = _T("80487/DX2/DX2 Overdrive");
  533.                       break;
  534.  
  535.               case 4: cpuString = _T("80486SL");
  536.                       break;
  537.  
  538.               case 5: cpuString = _T("80486SX2");
  539.                       break;
  540.  
  541.               case 6: cpuString = _T("80486DX (write-back)");
  542.                       break;
  543.  
  544.               case 7: cpuString = _T("80486DX4/DX4 Overdrive");
  545.                       break;
  546.  
  547.               case 8: cpuString = _T("80486DX4");
  548.                       break;
  549.  
  550.               case 9: cpuString = _T("80486DX4 (write-back)");
  551.                       break;
  552.  
  553.               default:cpuString = _T("Unknown 80486");
  554.                       noFamily = true;
  555.                       break;
  556.             }
  557.             break;
  558.  
  559.     case 5: switch( modelid )
  560.             {
  561.               case 1: if( typid == 1 )
  562.                         cpuString = _T("Pentium OverDrive (60,66)");
  563.                       else
  564.                         cpuString = _T("Pentium (60,66)");
  565.                       break;
  566.  
  567.               case 2: if( typid == 1 )
  568.                         cpuString = _T("Pentium (75,90,100,120,133,150,166,200)");
  569.                       else
  570.                         cpuString = _T("Pentium OverDrive (75,90,100,120,133,150,166,200)");
  571.                       break;
  572.  
  573.               case 3: cpuString = _T("Pentium Overdrive (for 80486)");
  574.                       break;
  575.  
  576.               case 4: if( typid == 1 )
  577.                         cpuString = _T("Pentium OverDrive MMC (75,90,100,120,133)");
  578.                       else
  579.                         cpuString = _T("Pentium MMX (166,200)");
  580.                       break;
  581.  
  582.               case 7: cpuString = _T("P54C");
  583.                       break;
  584.  
  585.               case 8: cpuString = _T("P55C");
  586.                       structureSize = _T("0.25╡m");
  587.                       break;
  588.  
  589.               default:cpuString = _T("Unknown Pentium");
  590.                       noFamily = true;
  591.                       break;
  592.             }
  593.             break;
  594.  
  595.     case 6: switch( modelid )
  596.             {
  597.               case 0: cpuString = _T("Pentium Pro (A-Step)");
  598.                       break;
  599.  
  600.               case 1: cpuString = _T("Pentium Pro");
  601.                       break;
  602.  
  603.               case 3: if( typid == 1 )
  604.                       {
  605.                         cpuString = _T("Pentium II OverDrive");
  606.                         structureSize = _T("0.28╡m");
  607.                       }
  608.                       else
  609.                       {
  610.                         cpuString = _T("Intel Pentium II");
  611.                         coreType = _T("Klamath");
  612.                         structureSize = _T("0.28╡m");
  613.                       }
  614.                       break;
  615.  
  616.               case 5: cpuString = _T("Intel Pentium II/II Xeon/Celeron");
  617.                       structureSize = _T("0.25╡m");
  618.                       break;
  619.  
  620.               case 6: cpuString = _T("Intel Pentium II/Celeron w/ on-die-L2");
  621.                       break;
  622.  
  623.               case 7: cpuString = _T("Intel Pentium III/III Xeon");
  624.                       structureSize = _T("0.25╡m");
  625.                       break;
  626.  
  627.               case 8: cpuString = _T("Intel Pentium III/III Xeon/Celeron");
  628.                       coreType = _T("Coppermine");
  629.                       structureSize = _T("0.18╡m");
  630.                       cacheSize = _T("256 KB");
  631.                       break;
  632.  
  633.               case 9: cpuString = _T("Intel Pentium-M");
  634.                       structureSize = _T("0.13╡m");
  635.                       coreType = _T("Banias");
  636.                       cacheSize = _T("1 MB");
  637.                       break;
  638.  
  639.               case 10:cpuString = _T("Intel Pentium III/PIII Xeon");
  640.                       structureSize = _T("0.18╡m");
  641.                       cacheSize = _T("2 MB");
  642.                       coreType = _T("Coppermine");
  643.                       break;
  644.  
  645.               case 11:cpuString = _T("Intel Pentium III");
  646.                       structureSize = _T("0.13╡m");
  647.                       cacheSize = _T("512 KB");
  648.                       coreType = _T("Tualatin");
  649.                       break;
  650.  
  651.               case 13:if( steppingid != 8 )
  652.                       {
  653.                         cpuString = _T("Intel Pentium-M");
  654.                         structureSize = _T("0.09╡m");
  655.                         cacheSize = _T("2 MB");
  656.                         coreType = _T("Dothan");
  657.                       }
  658.                       else
  659.                       {
  660.                         cpuString = _T("Intel Pentium-M");
  661.                         structureSize = _T("0.09╡m");
  662.                         cacheSize = _T("2 MB");
  663.                         coreType = _T("Sonoma");
  664.                       }
  665.                       break;
  666.  
  667.               case 14:cpuString = _T("Intel Pentium-M");
  668.                       structureSize = _T("65nm");
  669.                       cacheSize = _T("2 MB");
  670.                       coreType = _T("Yonah/Core Duo");
  671.                       break;
  672.  
  673.               case 15:cpuString = _T("Intel Pentium-M");
  674.                       structureSize = _T("65nm");
  675.                       cacheSize = _T("4 MB");
  676.                       coreType = _T("Core 2");
  677.                       break;
  678.  
  679.               default:cpuString = _T("Unknown Pentium Pro/II/III/M");
  680.                       noFamily = true;
  681.                       break;
  682.             }
  683.             break;
  684.  
  685.     case 15:switch( modelid )
  686.             {
  687.               case 0: cpuString = _T("Intel Pentium 4");
  688.                       structureSize = _T("0.18╡m");
  689.                       coreType = _T("Willamette");
  690.                       break;
  691.  
  692.               case 1: cpuString = _T("Intel Pentium 4");
  693.                       structureSize = _T("0.18╡m");
  694.                       coreType = _T("Willamette");
  695.                       break;
  696.  
  697.               case 2: cpuString = _T("Intel Pentium 4");
  698.                       structureSize = _T("0.13╡m");
  699.                       cacheSize = _T("512 KB");
  700.                       coreType = _T("Northwood");
  701.                       break;
  702.  
  703.               case 3: cpuString = _T("Intel Pentium 4");
  704.                       structureSize = _T("0.09╡m");
  705.                       cacheSize = _T("1 MB");
  706.                       coreType = _T("Prescott");
  707.                       break;
  708.  
  709.               case 4: cpuString = _T("Intel Pentium 4 Xeon");
  710.                       structureSize = _T("0.09╡m");
  711.                       cacheSize = _T("1 MB");
  712.                       coreType = _T("Prescott");
  713.                       break;
  714.  
  715.               case 6: cpuString = _T("Intel Pentium 4");
  716.                       structureSize = _T("65nm");
  717.                       cacheSize = _T("2 MB");
  718.                       break;
  719.  
  720.               default:cpuString = _T("Unknown Pentium 4");
  721.                       noFamily = true;
  722.                       break;
  723.             }
  724.             break;
  725.  
  726.     default:cpuString = _T("Unknown Intel CPU");
  727.             noFamily = true;
  728.             break;
  729.   }
  730.  
  731.   _tcscpy_s( cpuStr, cpuString );
  732.  
  733.   TCHAR* bstr = _T("");
  734.  
  735.   switch( brandID & 255 )
  736.   {
  737.     case 1: bstr = _T("Intel Celeron");
  738.             structureSize = _T("0.18╡m");
  739.             coreType = _T("Coppermine");
  740.             break;
  741.  
  742.     case 2: bstr = _T("Intel Pentium III");
  743.             structureSize = _T("0.18╡m");
  744.             coreType = _T("Coppermine");
  745.             break;
  746.  
  747.     case 3: bstr = _T("Intel Celeron/Pentium III Xeon");
  748.             structureSize = _T("0.18╡m");
  749.             coreType = _T("Coppermine");
  750.             break;
  751.  
  752.     case 4: bstr = _T("Intel Pentium III");
  753.             structureSize = _T("0.13╡m");
  754.             coreType = _T("Tualatin");
  755.             break;
  756.  
  757.     case 6: bstr = _T("Intel Mobile Pentium III-M");
  758.             structureSize = _T("0.13╡m");
  759.             coreType = _T("Tualatin");
  760.             break;
  761.  
  762.     case 7: bstr = _T("Intel Mobile Celeron");
  763.             structureSize = _T("0.13╡m");
  764.             coreType = _T("Tualatin");
  765.             break;
  766.  
  767.     case 8: if( family == 0xf24 )
  768.             {
  769.               bstr = _T("Intel Mobile Celeron 4");
  770.               structureSize = _T("0.13╡m");
  771.               coreType = _T("Northwood");
  772.             }
  773.             else
  774.             {
  775.               bstr = _T("Intel Pentium 4");
  776.               structureSize = _T("0.18╡m");
  777.               coreType = _T("Willamette");
  778.             }
  779.             break;
  780.  
  781.     case 9: bstr = _T("Intel Pentium 4");
  782.             structureSize = _T("0.13╡m");
  783.             coreType = _T("Northwood");
  784.             break;
  785.  
  786.     case 10:bstr = _T("Intel Celeron 4");
  787.             structureSize = _T("0.18╡m");
  788.             coreType = _T("Willamette");
  789.             break;
  790.  
  791.     case 11:if( familyid==15 && modelid==2 )
  792.             {
  793.               bstr = _T("Intel Pentium 4 Xeon");
  794.               structureSize = _T("0.13╡m");
  795.               coreType = _T("Northwood");
  796.             }
  797.             else
  798.             {
  799.               bstr = _T("Intel Pentium 4 Xeon");
  800.               structureSize = _T("0.18╡m");
  801.               coreType = _T("Willamette");
  802.             }
  803.             break;
  804.  
  805.     case 12:bstr = _T("Intel Pentium 4 Xeon MP");
  806.             structureSize = _T("0.13╡m");
  807.             coreType = _T("Northwood");
  808.             break;
  809.  
  810.     case 14:bstr = _T("Intel Mobile Pentium 4-M");
  811.             structureSize = _T("0.13╡m");
  812.             coreType = _T("Northwood");
  813.             cacheSize = _T("512 KB");
  814.             break;
  815.  
  816.     case 15:if( family == 0xf27 )
  817.               bstr = _T("Intel Mobile Celeron 4");
  818.             else
  819.               bstr = _T("Intel Mobile Pentium 4-M");
  820.             structureSize = _T("0.13╡m");
  821.             coreType = _T("Northwood");
  822.             break;
  823.  
  824.     case 22:if( familyid==6 && modelid==9 )
  825.             {
  826.               bstr = _T("Intel Pentium-M");
  827.               structureSize = _T("0.13╡m");
  828.               cacheSize = _T("1 MB");
  829.               coreType = _T("Banias");
  830.             }
  831.             else
  832.             {
  833.               bstr = _T("Intel Pentium-M");
  834.               structureSize = _T("0.09╡m");
  835.               cacheSize = _T("2 MB");
  836.               coreType = _T("Dothan");
  837.             }
  838.             break;
  839.   }
  840.  
  841.   if( *bstr )
  842.   {
  843.     _tcscpy_s( cpuStr, bstr );
  844.     brandStr = bstr;
  845.   }
  846.   else
  847.     brandStr = cpuString;
  848. }
  849.  
  850. void CCPUData::identifyAMD()
  851. {
  852.   switch( familyid )
  853.   {
  854.     case 4: switch( modelid )
  855.             {
  856.               case 3: _tcscpy_s( cpuStr, _T("486DX/2") );
  857.                       break;
  858.  
  859.               case 7: _tcscpy_s( cpuStr, _T("486DX/2-WB") );
  860.                       break;
  861.  
  862.               case 8: _tcscpy_s( cpuStr, _T("486DX/4") );
  863.                       break;
  864.  
  865.               case 9: _tcscpy_s( cpuStr, _T("486DX/4-WB") );
  866.                       break;
  867.  
  868.               case 14:_tcscpy_s( cpuStr, _T("Am5x86-WT") );
  869.                       break;
  870.  
  871.               case 15:_tcscpy_s( cpuStr, _T("Am5x86-WB") );
  872.                       break;
  873.  
  874.               default:_tcscpy_s( cpuStr, _T("Unknown 486/5x86 CPU") );
  875.                       break;
  876.             }
  877.             break;
  878.  
  879.     case 5: switch( modelid )
  880.             {
  881.               case 0: _tcscpy_s( cpuStr, _T("K5/SSA5 (PR75...PR100)") );
  882.                       break;
  883.  
  884.               case 1: _tcscpy_s( cpuStr, _T("K5 (PR120/PR133)") );
  885.                       break;
  886.  
  887.               case 2: _tcscpy_s( cpuStr, _T("K5 (PR150/PR166)") );
  888.                       break;
  889.  
  890.               case 3: _tcscpy_s( cpuStr, _T("K5 (PR200)") );
  891.                       break;
  892.  
  893.               case 6: _tcscpy_s( cpuStr, _T("K6 (166...233MHz)") );
  894.                       break;
  895.  
  896.               case 7: _tcscpy_s( cpuStr, _T("K6 (266...300MHz)") );
  897.                       break;
  898.  
  899.               case 8: _tcscpy_s( cpuStr, _T("K6-2 w/ 3DNow!") );
  900.                       break;
  901.  
  902.               case 9: _tcscpy_s( cpuStr, _T("K6-3 w/ 3DNow!") );
  903.                       break;
  904.  
  905.               case 13:_tcscpy_s( cpuStr, _T("K6-2+ / K6-III+ w/ 3DNow!") );
  906.                       break;
  907.  
  908.               default:_tcscpy_s( cpuStr, _T("Unknown K6 CPU") );
  909.                       break;
  910.             }
  911.             break;
  912.  
  913.     case 6: switch( modelid )
  914.             {
  915.               case 0:
  916.               case 1: _tcscpy_s( cpuStr, _T("Athlon (25um)") );
  917.                       break;
  918.  
  919.               case 2: _tcscpy_s( cpuStr, _T("Athlon (18um)") );
  920.                       break;
  921.  
  922.               case 3: _tcscpy_s( cpuStr, _T("Duron") );
  923.                       break;
  924.  
  925.               case 4: _tcscpy_s( cpuStr, _T("Athlon (Thunderbird)") );
  926.                       break;
  927.  
  928.               case 6: _tcscpy_s( cpuStr, _T("Athlon (Palomino)") );
  929.                       break;
  930.  
  931.               case 7: _tcscpy_s( cpuStr, _T("Duron (Morgan)") );
  932.                       break;
  933.  
  934.               default:_tcscpy_s( cpuStr, _T("Unknown Athlon") );
  935.                       break;
  936.             }
  937.             break;
  938.  
  939.     default:_tcscpy_s( cpuStr, _T("Unknown AMD CPU") );
  940.             break;
  941.   }
  942. }
  943.  
  944. void CCPUData::identifyCyrix()
  945. {
  946.   switch( familyid )
  947.   {
  948.     case 4: switch( modelid )
  949.             {
  950.               case 4: _tcscpy_s( cpuStr, _T("MediaGX") );
  951.                       break;
  952.  
  953.               default:_tcscpy_s( cpuStr, _T("Unknown Cyrix CPU") );
  954.                       break;
  955.             }
  956.             break;
  957.  
  958.     case 5: switch( modelid )
  959.             {
  960.               case 2: _tcscpy_s( cpuStr, _T("6x86/6x86L") );
  961.                       break;
  962.  
  963.               case 4: _tcscpy_s( cpuStr, _T("MediaGX MMX enh.") );
  964.                       break;
  965.  
  966.               default:_tcscpy_s( cpuStr, _T("Unknown Cyrix CPU") );
  967.                       break;
  968.             }
  969.             break;
  970.      
  971.     case 6: switch( modelid )
  972.             {
  973.               case 0: _tcscpy_s( cpuStr, _T("m II") );
  974.                       break;
  975.  
  976.               case 5: _tcscpy_s( cpuStr, _T("VIA Cyrix M2 core") );
  977.                       break;
  978.  
  979.               case 6: _tcscpy_s( cpuStr, _T("WinChip C5A") );
  980.                       break;
  981.  
  982.               case 7: _tcscpy_s( cpuStr, _T("WinChip C5B") );
  983.                       break;
  984.  
  985.               default:_tcscpy_s( cpuStr, _T("Unknown Cyrix CPU") );
  986.                       break;
  987.             }
  988.             break;
  989.  
  990.     default:_tcscpy_s( cpuStr, _T("Unknown Cyrix CPU") );
  991.             break;
  992.   }
  993. }
  994.  
  995. void CCPUData::init()
  996. {
  997.   features = 0;
  998.   exfeatures = 0;
  999.   typid = 0;
  1000.   modelid = 0;
  1001.   steppingid = 0;
  1002.   *vendorID = '\0';
  1003.   vendor = -1;
  1004.   maxIDVal = 0;
  1005.   exlevel = 0;
  1006.   brandID = 0;
  1007.   exfeatures2 = 0;
  1008.   brandStr = _T("");
  1009.   cacheSize = NULL;
  1010.   structureSize = NULL;
  1011.   coreType = NULL;
  1012.   cacheStrNo = 0;
  1013.   flagNo = 0;
  1014.  
  1015.   f_fpu = f_vme = f_de = f_pse = f_tsc = f_msr = f_pae = f_mce = f_c8x = f_apic = f_sep = 
  1016.   f_mtrr = f_pge = f_mca = f_cmov = f_pse36 = f_psn = f_mmx = f_pat = f_fxsr = f_sse = f_sse2 = 
  1017.   f_fsc = f_fcmov = f_mmxext = f_3dnowext = f_3dnow = f_cxmmx = f_ss = f_htt = f_tm1 = f_ia64 = 
  1018.   f_acpi = f_pbe = f_sse3 = f_mon = f_cpl = f_vmx = f_est = f_tm2 = f_l1id = f_c16b = FALSE;
  1019. }
  1020.  
  1021. void CCPUData::getCPUFeatures()
  1022. {
  1023.   DWORD cpuff = 0;
  1024.   DWORD cpuffext = 0;
  1025.   DWORD bid = 0;
  1026.   DWORD fam = 0;
  1027.   BYTE vid[16] = "------------";
  1028.   DWORD maxl = 0;
  1029.  
  1030.   __asm {      
  1031.       pushad
  1032.       xor eax,eax
  1033.       CPU_ID
  1034.       mov dword ptr vid,ebx
  1035.       mov dword ptr vid[+4],edx
  1036.       mov dword ptr vid[+8],ecx
  1037.       mov dword ptr maxl,eax
  1038.  
  1039.       cmp eax,1
  1040.       jl end_cpuff
  1041.       xor eax,eax
  1042.       inc eax
  1043.       CPU_ID
  1044.       mov cpuff,edx
  1045.       mov cpuffext,ecx
  1046.       mov bid,ebx
  1047.       mov fam,eax
  1048.  
  1049.     end_cpuff:
  1050.       popad
  1051.   }
  1052.  
  1053. #ifdef _UNICODE
  1054.   wchar_t pstrw[16];
  1055.   char2uc( (char*)pstrw, (char*)vid );
  1056.   _tcscpy_s( vendorID, pstrw );
  1057. #else
  1058.   strcpy_s( vendorID, (char*)vid );
  1059. #endif
  1060.  
  1061.   family = fam;
  1062.   brandID = bid;
  1063.   features = cpuff;
  1064.   exfeatures = cpuffext;
  1065.   maxIDVal = maxl;
  1066. }
  1067.  
  1068. /////////////////////////////////////////////////////////////////////////////
  1069. void CCPUData::Message( LPCTSTR lpszMessage )
  1070. {
  1071.   if( flagNo < 64 )
  1072.     flag[flagNo++] = lpszMessage;
  1073.  
  1074.   _tcscat_s( flagText, lpszMessage );
  1075.   _tcscat_s( flagText, _T("\r\n") );
  1076. }
  1077.  
  1078. void CCPUData::readCPUIDLevel( int level, int level2, ULONG* target )
  1079. {
  1080.   ULONG x[4];
  1081.  
  1082.   __asm {      
  1083.       pushad
  1084.       mov eax,level
  1085.       mov ecx,level2
  1086.       CPU_ID
  1087.       mov dword ptr x,eax
  1088.       mov dword ptr x[+4],ebx
  1089.       mov dword ptr x[+8],ecx
  1090.       mov dword ptr x[+12],edx
  1091.       popad
  1092.   }
  1093.  
  1094.   target[0] = x[0];
  1095.   target[1] = x[1];
  1096.   target[2] = x[2];
  1097.   target[3] = x[3];
  1098. }
  1099.  
  1100. static CACHEID cids[] = 
  1101. {
  1102.   { 0x06, _T("L1 instruction cache: 8 KBytes, 4-way set associative, 32 byte line size") },
  1103.   { 0x08, _T("L1 instruction cache: 16 KBytes, 4-way set associative, 32 byte line size") },
  1104.   { 0x0a, _T("L1 data cache: 8 KBytes, 2-way set associative, 32 byte line size") },
  1105.   { 0x0c, _T("L1 data cache: 16 KBytes, 4-way set associative, 32 byte line size") },
  1106.   { 0x22, _T("L3 cache: 512 KBytes, 4-way set associative, 64 byte line size, 2 lines per sector") },
  1107.   { 0x23, _T("L3 cache: 1 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector") },
  1108.   { 0x25, _T("L3 cache: 2 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector") },
  1109.   { 0x29, _T("L3 cache: 4 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector") },
  1110.   { 0x2c, _T("L1 data cache: 32 KBytes, 8-way set associative, 64 byte line size") },
  1111.   { 0x30, _T("L1 instruction cache: 32 KBytes, 8-way set associative, 64 byte line size") },
  1112.   { 0x41, _T("L2 cache: 128 KBytes, 4-way set associative, 32 byte line size") },
  1113.   { 0x42, _T("L2 cache: 256 KBytes, 4-way set associative, 32 byte line size") },
  1114.   { 0x43, _T("L2 cache: 512 KBytes, 4-way set associative, 32 byte line size") },
  1115.   { 0x44, _T("L2 cache: 1 MByte, 4-way set associative, 32 byte line size") },
  1116.   { 0x45, _T("L2 cache: 2 MByte, 4-way set associative, 32 byte line size") },
  1117.   { 0x46, _T("L3 cache: 4 MByte, 4-way set associative, 64 byte line size") },
  1118.   { 0x47, _T("L3 cache: 8 MByte, 8-way set associative, 64 byte line size") },
  1119.   { 0x60, _T("L1 data cache: 16 KByte, 8-way set associative, 64 byte line size") },
  1120.   { 0x66, _T("L1 data cache: 8 KByte, 4-way set associative, 64 byte line size") },
  1121.   { 0x67, _T("1 data cache: 16 KByte, 4-way set associative, 64 byte line size") },
  1122.   { 0x68, _T("L1 data cache: 32 KByte, 4-way set associative, 64 byte line size") },
  1123.   { 0x70, _T("Trace cache: 12K-╡op, 8-way set associative") },
  1124.   { 0x71, _T("Trace cache: 16K-╡op, 8-way set associative") },
  1125.   { 0x72, _T("Trace cache: 32K-╡op, 8-way set associative") },
  1126.   { 0x78, _T("L2 cache: 1 MByte, 4-way set associative, 64byte line size") },
  1127.   { 0x79, _T("L2 cache: 128 KByte, 8-way set associative, 64 byte line size, 2 lines per sector") },
  1128.   { 0x7a, _T("L2 cache: 256 KByte, 8-way set associative, 64 byte line size, 2 lines per sector") },
  1129.   { 0x7b, _T("L2 cache: 512 KByte, 8-way set associative, 64 byte line size, 2 lines per sector") },
  1130.   { 0x7c, _T("L2 cache: 1 MByte, 8-way set associative, 64 byte line size, 2 lines per sector") },
  1131.   { 0x7d, _T("L2 cache: 2 MByte, 8-way set associative, 64byte line size") },
  1132.   { 0x7f, _T("L2 cache: 512 KByte, 2-way set associative, 64-byte line size") },
  1133.   { 0x82, _T("L2 cache: 256 KByte, 8-way set associative, 32 byte line size") },
  1134.   { 0x83, _T("L2 cache: 512 KByte, 8-way set associative, 32 byte line size") },
  1135.   { 0x84, _T("L2 cache: 1 MByte, 8-way set associative, 32 byte line size") },
  1136.   { 0x85, _T("L2 cache: 2 MByte, 8-way set associative, 32 byte line size") },
  1137.   { 0x86, _T("L2 cache: 512 KByte, 4-way set associative, 64 byte line size") },
  1138.   { 0x87, _T("L2 cache: 1 MByte, 8-way set associative, 64 byte line size") },
  1139.   { 0x00, NULL }
  1140. };
  1141.  
  1142. void CCPUData::readCacheInfo()
  1143. {
  1144.   ULONG cid[4];
  1145.   
  1146.   readCPUIDLevel( 2, 0, cid );
  1147.  
  1148.   for( int i=0; i<4; i++ )
  1149.   {
  1150.     // MSB darf nicht gesetzt sein (EAX, EBX, ECX, EDX)
  1151.     if( !(cid[i] & (1<<31)) )
  1152.     {
  1153.       // LSByte von EAX (AL) ignorieren
  1154.       if( i != 0 )
  1155.         printCacheInfo( cid[i] & 0xff );
  1156.  
  1157.       printCacheInfo( (cid[i]>>8) & 0xff );
  1158.       printCacheInfo( (cid[i]>>16) & 0xff );
  1159.       printCacheInfo( (cid[i]>>24) & 0xff );
  1160.     }
  1161.   }
  1162. }
  1163.  
  1164. void CCPUData::printCacheInfo( int value )
  1165. {
  1166.   int i=0;
  1167.  
  1168.   if( value <= 0 )
  1169.     return;
  1170.  
  1171.   for( ;; )
  1172.   {
  1173.     if( cids[i].id == 0 )
  1174.       break;
  1175.     else if( cids[i].id == value )
  1176.     {
  1177.       if( cacheStrNo < 31 )
  1178.         cacheStr[cacheStrNo++] = (CString)cids[i].text;
  1179.  
  1180.       break;
  1181.     }
  1182.     
  1183.     i++;
  1184.   }
  1185. }
  1186.