diff --git a/src/detection/cpu/cpu.h b/src/detection/cpu/cpu.h index 9586e686e..cef5a14b7 100644 --- a/src/detection/cpu/cpu.h +++ b/src/detection/cpu/cpu.h @@ -19,4 +19,5 @@ typedef struct FFCPUResult double temperature; } FFCPUResult; +const char* ffCPUDetectByCpuid(FFCPUResult* cpu); const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu); diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c index 2f3ec2de7..62a317615 100644 --- a/src/detection/cpu/cpu_apple.c +++ b/src/detection/cpu/cpu_apple.c @@ -68,7 +68,7 @@ static const char* detectFrequency(FFCPUResult* cpu) #else static const char* detectFrequency(FFCPUResult* cpu) { - cpu->frequencyMin = ffSysctlGetInt64("hw.cpufrequency_min", 0) / 1000.0 / 1000.0 / 1000.0; + cpu->frequencyMin = ffSysctlGetInt64("hw.cpufrequency", 0) / 1000.0 / 1000.0 / 1000.0; cpu->frequencyMax = ffSysctlGetInt64("hw.cpufrequency_max", 0); if(cpu->frequencyMax > 0.0) cpu->frequencyMax /= 1000.0 * 1000.0 * 1000.0; diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 00936133a..6fc8cc555 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -94,11 +94,14 @@ static double getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, cons if (ok) return ffStrbufToDouble(buffer) / 1e6; - ffStrbufAppendS(basePath, scalingFileName); - ok = ffReadFileBuffer(basePath->chars, buffer); - ffStrbufSubstrBefore(basePath, baseLen); - if (ok) - return ffStrbufToDouble(buffer) / 1e6; + if (scalingFileName) + { + ffStrbufAppendS(basePath, scalingFileName); + ok = ffReadFileBuffer(basePath->chars, buffer); + ffStrbufSubstrBefore(basePath, baseLen); + if (ok) + return ffStrbufToDouble(buffer) / 1e6; + } return 0.0/0.0; } @@ -119,19 +122,19 @@ static bool detectFrequency(FFCPUResult* cpu) if (ffStrStartsWith(entry->d_name, "policy") && isdigit(entry->d_name[strlen("policy")])) { ffStrbufAppendS(&path, entry->d_name); - double fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer); - if (fmin != fmin) continue; + double fbase = getFrequency(&path, "/base_frequency", NULL, &buffer); + if (fbase != fbase) continue; double fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer); if (fmax != fmax) continue; if (flag) { - cpu->frequencyMin = cpu->frequencyMin < fmin ? cpu->frequencyMin : fmin; + cpu->frequencyMin = cpu->frequencyMin > fbase ? cpu->frequencyMin : fbase; cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax; } else { - cpu->frequencyMin = fmin; + cpu->frequencyMin = fbase; cpu->frequencyMax = fmax; flag = true; } diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index 1bb169d74..874997b34 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -76,38 +76,42 @@ static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu) return NULL; } -static const char* detectByOS(FFCPUResult* cpu) +static const char* detectNCores(FFCPUResult* cpu) { + DWORD length = 0; + GetLogicalProcessorInformationEx(RelationAll, NULL, &length); + if (length == 0) + return "GetLogicalProcessorInformationEx(RelationAll, NULL, &length) failed"; + + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* FF_AUTO_FREE + pProcessorInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(length); + + if (!pProcessorInfo || !GetLogicalProcessorInformationEx(RelationAll, pProcessorInfo, &length)) + return "GetLogicalProcessorInformationEx(RelationAll, pProcessorInfo, &length) failed"; + + for( + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* ptr = pProcessorInfo; + (uint8_t*)ptr < ((uint8_t*)pProcessorInfo) + length; + ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((uint8_t*)ptr) + ptr->Size) + ) { - DWORD length = 0; - GetLogicalProcessorInformationEx(RelationAll, NULL, &length); - if (length == 0) - return "GetLogicalProcessorInformationEx(RelationAll, NULL, &length) failed"; - - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* FF_AUTO_FREE - pProcessorInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(length); - - if (pProcessorInfo && GetLogicalProcessorInformationEx(RelationAll, pProcessorInfo, &length)) + if(ptr->Relationship == RelationProcessorCore) + ++cpu->coresPhysical; + else if(ptr->Relationship == RelationGroup) { - for( - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* ptr = pProcessorInfo; - (uint8_t*)ptr < ((uint8_t*)pProcessorInfo) + length; - ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((uint8_t*)ptr) + ptr->Size) - ) + for (uint32_t index = 0; index < ptr->Group.ActiveGroupCount; ++index) { - if(ptr->Relationship == RelationProcessorCore) - ++cpu->coresPhysical; - else if(ptr->Relationship == RelationGroup) - { - cpu->coresOnline += ptr->Group.GroupInfo->ActiveProcessorCount; - cpu->coresLogical += ptr->Group.GroupInfo->MaximumProcessorCount; - } + cpu->coresOnline += ptr->Group.GroupInfo[index].ActiveProcessorCount; + cpu->coresLogical += ptr->Group.GroupInfo[index].MaximumProcessorCount; } } - else - return "GetLogicalProcessorInformationEx(RelationAll, pProcessorInfo, &length) failed"; } + return NULL; +} + +static const char* detectByRegistry(FFCPUResult* cpu) +{ FF_HKEY_AUTO_DESTROY hKey = NULL; if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey, NULL)) return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\", &hKey, NULL) failed"; @@ -121,18 +125,28 @@ static const char* detectByOS(FFCPUResult* cpu) ffRegReadStrbuf(hKey, L"ProcessorNameString", &cpu->name, NULL); ffRegReadStrbuf(hKey, L"VendorIdentifier", &cpu->vendor, NULL); + if (cpu->coresLogical == 0) + { + DWORD cores; + if (RegQueryInfoKeyW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor", NULL, NULL, &cores, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + cpu->coresOnline = cpu->coresPhysical = cpu->coresLogical = (uint16_t) cores; + } + return NULL; } const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) { - const char* error = detectByOS(cpu); + detectNCores(cpu); + + const char* error = detectByRegistry(cpu); if (error) return error; + detectMaxSpeedBySmbios(cpu); + if(options->temp) ffDetectSmbiosTemp(&cpu->temperature, NULL); - detectMaxSpeedBySmbios(cpu); return NULL; } diff --git a/src/util/windows/registry.c b/src/util/windows/registry.c index 998bfaf3c..a324527cd 100644 --- a/src/util/windows/registry.c +++ b/src/util/windows/registry.c @@ -154,3 +154,17 @@ bool ffRegGetSubKey(HKEY hKey, uint32_t index, FFstrbuf* result, FFstrbuf* error ffStrbufSetWS(result, resultW); return true; } + +bool ffRegGetNSubKeys(HKEY hKey, uint32_t* result, FFstrbuf* error) +{ + DWORD buffer; + if(RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &buffer, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) + { + if (error) + ffStrbufAppendS(error, "RegQueryInfoKeyW(hKey) failed"); + return false; + } + + *result = buffer; + return true; +} diff --git a/src/util/windows/registry.h b/src/util/windows/registry.h index 42dd08aaf..959fea5e3 100644 --- a/src/util/windows/registry.h +++ b/src/util/windows/registry.h @@ -21,5 +21,6 @@ bool ffRegReadData(HKEY hKey, const wchar_t* valueNameW, uint8_t** result, uint3 bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error); bool ffRegReadUint64(HKEY hKey, const wchar_t* valueNameW, uint64_t* result, FFstrbuf* error); bool ffRegGetSubKey(HKEY hKey, uint32_t index, FFstrbuf* result, FFstrbuf* error); +bool ffRegGetNSubKeys(HKEY hKey, uint32_t* result, FFstrbuf* error); #endif