Skip to content

Commit

Permalink
feat: add disk feature detection for MacOS (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
aminya authored Jul 7, 2024
1 parent 0b66444 commit 5ce95ec
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/**/build/**
/.vs
/CMakeSettings.json
/.cache/
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" PROJECT

option(BUILD_EXAMPLES "Build example program" ${PROJECT_IS_TOP_LEVEL})
option(BUILD_TESTING "Build test program" ${PROJECT_IS_TOP_LEVEL})
option(NO_OCL "Disable OCL" OFF)

# set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")

Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ hwinfo builds using C++20. However, if your compiler does not support C++20, you
| | Version | ✔️ || ✔️ |
| | Serial-Number ||| ✔️ |
| | Bios ||||
| Disk | Vendor | ✔️ | | ✔️ |
| | Model | ✔️ | | ✔️ |
| | Serial-Number | | | ✔️ |
| | Size | | | |
| Disk | Vendor | ✔️ | ✔️ | ✔️ |
| | Model | ✔️ | ✔️ | ✔️ |
| | Serial-Number | ✔️ | ✔️ | ✔️ |
| | Size | ✔️ | ✔️ | ✔️ |
| Operating System | Name | ✔️ | ✔️ | ✔️ |
| | Short Name | ✔️ | ❌️ | ✔️ |
| | Version | ✔️ | ✔️ ||
Expand Down Expand Up @@ -242,13 +242,13 @@ Disk 4:
2. Simply add the following to your `<project-root>/CMakeLists.txt` file:
```cmake
# file: <project-root>/CMakeLists.txt
add_subdirectory(third_party/hwinfo)
```
3. Include `hwinfo` into your `.cpp/.h` files:
```c++
// file: your_executable.cpp

#include "hwinfo/hwinfo.h"

int main(int argc, char** argv) {
Expand Down
1 change: 0 additions & 1 deletion include/hwinfo/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <hwinfo/platform.h>
#include <hwinfo/utils/wmi_wrapper.h>

#include <memory>
#include <string>
#include <vector>

Expand Down
2 changes: 2 additions & 0 deletions include/hwinfo/cpuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include <cpuid.h>
#endif

#include <cstdint>

#define MAX_INTEL_TOP_LVL 4

#define SSE_POS 0x02000000
Expand Down
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ if (WIN32 AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
target_link_libraries(HWinfo PUBLIC "wbemuuid")
endif ()

if (APPLE)
target_link_libraries(HWinfo PUBLIC "-framework IOKit" "-framework CoreFoundation")
endif()

if (NOT DEFINED NO_OCL)
target_link_libraries(HWinfo PUBLIC miss-opencl_static)
endif ()
Expand Down
9 changes: 6 additions & 3 deletions src/apple/cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
#include <mach/mach_time.h>
#include <sys/sysctl.h>

#include <cmath>
#include <string>
#include <vector>

#include "hwinfo/cpu.h"
#include "hwinfo/cpuid.h"

namespace hwinfo {

Expand Down Expand Up @@ -110,7 +110,8 @@ std::string getModelName() {
size_t size = 1024;
std::string model;
model.resize(size);
if (sysctlbyname("machdep.cpu.brand_string", model.data(), &size, nullptr, 0) == 0) {
if (sysctlbyname("machdep.cpu.brand_string", static_cast<void*>(const_cast<char*>(model.data())), &size, nullptr,
0) == 0) {
model.resize(size);
model.pop_back();
return model;
Expand All @@ -119,6 +120,8 @@ std::string getModelName() {
#endif
}

int getNumLogicalCores();

// _____________________________________________________________________________________________________________________
int getNumPhysicalCores() {
#if defined(HWINFO_X86)
Expand Down Expand Up @@ -229,4 +232,4 @@ std::vector<CPU> getAllCPUs() {

} // namespace hwinfo

#endif // HWINFO_APPLE
#endif // HWINFO_APPLE
125 changes: 116 additions & 9 deletions src/apple/disk.cpp
Original file line number Diff line number Diff line change
@@ -1,25 +1,132 @@
// Copyright Leon Freist
// Author Leon Freist <[email protected]>

#include "hwinfo/platform.h"
#include <hwinfo/platform.h>

#include <cstdint>

#ifdef HWINFO_APPLE

#include <fstream>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOBSD.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/storage/IOMedia.h>
#include <hwinfo/disk.h>

#include "hwinfo/disk.h"
#include "hwinfo/utils/stringutils.h"
#include <string>

namespace hwinfo {

// =====================================================================================================================
// _____________________________________________________________________________________________________________________
/**
Converts a CFStringRef to a std::string
*/
std::string cf_to_std(CFStringRef cfString) {
if (cfString == nullptr) {
return "<unknown>";
}

CFIndex length = CFStringGetLength(cfString);
CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;

// Initialize std::string with maxSize and fill with null characters
auto out = std::string(maxSize, '\0');

// Fill std::string with the actual string
auto success = CFStringGetCString(cfString, const_cast<char*>(out.data()), maxSize, kCFStringEncodingUTF8);

if (!success) {
return "<unknown>";
}

// Resize the string to the actual length
out.resize(strlen(out.c_str()));
return out;
}

/**
Converts a CFNumberRef to a number of type ReturnType
*/
template <typename NumberType>
NumberType cf_to_std(CFNumberRef raw, CFNumberType cfNumberEnum) {
if (raw == nullptr) {
return NumberType();
}

NumberType out;
CFNumberGetValue(raw, cfNumberEnum, &out);

return out;
}

int64_t cf_to_std(CFNumberRef raw) { return cf_to_std<int64_t>(raw, kCFNumberSInt64Type); }

template <typename ReturnType, typename CFType>
ReturnType getIORegistryProperty(io_object_t service, CFStringRef key) {
// Get the property from I/O Registry
auto raw = static_cast<CFType>(IORegistryEntryCreateCFProperty(service, key, kCFAllocatorDefault, 0));

// Convert the property to a output type
ReturnType out = cf_to_std(raw);

// Release the property
if (raw) {
CFRelease(raw);
};

return out;
}

// Retrieves disk information using I/O Kit
std::vector<Disk> getAllDisks() {
// TODO: implement
std::vector<Disk> disks;
auto disks = std::vector<Disk>();

CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOMediaClass);
CFDictionaryAddValue(matchingDict, CFSTR(kIOMediaWholeKey), kCFBooleanTrue);

io_iterator_t iter;
if (IOServiceGetMatchingServices(0, matchingDict, &iter) == KERN_SUCCESS) {
int i_disk = 0;
while (true) {
auto service = IOIteratorNext(iter);
if (service == 0) {
break;
}

auto disk = Disk();

disk._id = i_disk;

// get the name of the IO service
std::string model;
model.resize(128);
if (IORegistryEntryGetName(service, const_cast<char*>(model.data())) != KERN_SUCCESS) {
model = "<unknown>";
}
model.resize(strlen(model.c_str()));
disk._model = model;

// guess the vendor from the model
if (model.find("APPLE") != std::string::npos || model.find("Apple") != std::string::npos) {
disk._vendor = "Apple";
} else {
disk._vendor = "<unknown>";
}

disk._serialNumber = getIORegistryProperty<std::string, CFStringRef>(service, CFSTR(kIOMediaUUIDKey));

disk._size_Bytes = getIORegistryProperty<int64_t, CFNumberRef>(service, CFSTR(kIOMediaSizeKey));

disks.push_back(std::move(disk));

IOObjectRelease(service);

i_disk++;
}
IOObjectRelease(iter);
}
return disks;
}

} // namespace hwinfo

#endif // HWINFO_APPLE
#endif // HWINFO_APPLE
8 changes: 5 additions & 3 deletions src/apple/os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ OS::OS() {

std::string kernel_name;
kernel_name.resize(size);
if (sysctlbyname("kern.ostype", kernel_name.data(), &size, nullptr, 0) == 0) {
if (sysctlbyname("kern.ostype", static_cast<void*>(const_cast<char*>(kernel_name.data())), &size, nullptr, 0) == 0) {
kernel_name.resize(size); // trim the string to the actual size
kernel_name.pop_back(); // remove unprintable character at the end
_kernel = kernel_name;
Expand All @@ -31,7 +31,8 @@ OS::OS() {

std::string kernel_version;
kernel_version.resize(size);
if (sysctlbyname("kern.osrelease", kernel_version.data(), &size, nullptr, 0) == 0) {
if (sysctlbyname("kern.osrelease", static_cast<void*>(const_cast<char*>(kernel_version.data())), &size, nullptr, 0) ==
0) {
kernel_version.resize(size);
kernel_version.pop_back();

Expand All @@ -43,7 +44,8 @@ OS::OS() {
std::string os_version;
os_version.resize(size);

if (sysctlbyname("kern.osproductversion", os_version.data(), &size, nullptr, 0) == 0) {
if (sysctlbyname("kern.osproductversion", static_cast<void*>(const_cast<char*>(os_version.data())), &size, nullptr,
0) == 0) {
os_version.resize(size);
os_version.pop_back();
_version = os_version;
Expand Down

0 comments on commit 5ce95ec

Please sign in to comment.