126 lines
2.8 KiB
C++
Executable File
126 lines
2.8 KiB
C++
Executable File
//
|
|
// kern_keyvalue.hpp
|
|
// VirtualSMC
|
|
//
|
|
// Copyright © 2017 vit9696. All rights reserved.
|
|
//
|
|
|
|
#ifndef kern_keyvalue_hpp
|
|
#define kern_keyvalue_hpp
|
|
|
|
#include <stdatomic.h>
|
|
#include <VirtualSMCSDK/AppleSmcBridge.hpp>
|
|
#include <VirtualSMCSDK/kern_value.hpp>
|
|
|
|
struct VirtualSMCKeyValue {
|
|
/**
|
|
* Key name
|
|
*/
|
|
SMC_KEY key;
|
|
|
|
/**
|
|
* Key value
|
|
*/
|
|
_Atomic(VirtualSMCValue *) value = ATOMIC_VAR_INIT(nullptr);
|
|
|
|
/**
|
|
* Original value
|
|
*/
|
|
_Atomic(VirtualSMCValue *) backup = nullptr;
|
|
|
|
/**
|
|
* Should key value pair be serialisable
|
|
*
|
|
* @param confidential confidential serialisation stores are allowed
|
|
*
|
|
* @return true if should be saved
|
|
*/
|
|
bool serializable(bool confidential) const;
|
|
|
|
/**
|
|
* Get serialized size (normally key, size, key data)
|
|
*
|
|
* @return size in bytes
|
|
*/
|
|
size_t serializedSize() const;
|
|
|
|
/**
|
|
* Write serialized data to the buffer
|
|
*
|
|
* @param dst serialization buffer reference of at least serializedSize()
|
|
*/
|
|
void serialize(uint8_t *&dst) const;
|
|
|
|
/**
|
|
* Read serialized data
|
|
*
|
|
* @param src serialization buffer reference (increased)
|
|
* @param size serialization buffer size (decreased)
|
|
* @param name read key name
|
|
* @param out read key data (must be preallocated)
|
|
* @param outsz key data size
|
|
*
|
|
* @return true on succesful read
|
|
*/
|
|
static bool deserialize(const uint8_t *&src, uint32_t &size, SMC_KEY &name, SMC_DATA *out, SMC_DATA_SIZE &outsz);
|
|
|
|
/**
|
|
* Create key/value pair for storage
|
|
*
|
|
* @param k key name
|
|
* @param v key value
|
|
*
|
|
* @return key/value pair
|
|
*/
|
|
static VirtualSMCKeyValue create(SMC_KEY k, VirtualSMCValue *v) {
|
|
VirtualSMCKeyValue kv {k};
|
|
atomic_init(&kv.value, v);
|
|
atomic_init(&kv.backup, nullptr);
|
|
return kv;
|
|
}
|
|
|
|
/**
|
|
* Key/value deleter responsible for freeing value dynamic memory
|
|
*
|
|
* @param kv key/value pair
|
|
*/
|
|
static void deleter(VirtualSMCKeyValue &kv) {
|
|
// This is just an old compiler crash workaround, no need for atomicity here!
|
|
auto v = atomic_load_explicit(&kv.value, memory_order_relaxed);
|
|
auto b = atomic_load_explicit(&kv.backup, memory_order_relaxed);
|
|
if (v) VirtualSMCValue::deleter(v);
|
|
if (b) VirtualSMCValue::deleter(b);
|
|
}
|
|
|
|
/**
|
|
* Key comparator for sorting
|
|
*
|
|
* @param a first key
|
|
* @param b second key
|
|
*
|
|
* @return like qsort (<0 if a goes before b)
|
|
*/
|
|
static int compare(const SMC_KEY a, const SMC_KEY b) {
|
|
if (a == b)
|
|
return 0;
|
|
else if (OSSwapInt32(a) < OSSwapInt32(b))
|
|
return -1;
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Key value comparator for sorting
|
|
*
|
|
* @param a opaque k/v pointer
|
|
* @param b opaque k/v pointer
|
|
*
|
|
* @return like qsort (<0 if a goes before b)
|
|
*/
|
|
static int compare(const void *a, const void *b) {
|
|
return compare(static_cast<const VirtualSMCKeyValue *>(a)->key, static_cast<const VirtualSMCKeyValue *>(b)->key);
|
|
}
|
|
};
|
|
|
|
|
|
#endif /* kern_keyvalue_hpp */
|