2022-03-29 10:26:33 +03:00

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 */