mirror of
https://github.com/decompals/wibo.git
synced 2025-12-17 17:05:29 +00:00
Split advapi32 into separate files (part 2) & more impls for ee-gcc/cygwin
This commit is contained in:
@@ -33,11 +33,11 @@ constexpr PredefinedKeyInfo kPredefinedKeyInfos[] = {
|
||||
|
||||
constexpr size_t kPredefinedKeyCount = std::size(kPredefinedKeyInfos);
|
||||
|
||||
std::mutex registryMutex;
|
||||
bool predefinedHandlesInitialized = false;
|
||||
RegistryKeyHandleData predefinedHandles[kPredefinedKeyCount];
|
||||
bool registryInitialized = false;
|
||||
std::unordered_set<std::u16string> existingKeys;
|
||||
std::mutex g_registryMutex;
|
||||
bool g_predefinedHandlesInitialized = false;
|
||||
RegistryKeyHandleData g_predefinedHandles[kPredefinedKeyCount];
|
||||
bool g_registryInitialized = false;
|
||||
std::unordered_set<std::u16string> g_existingKeys;
|
||||
|
||||
std::u16string canonicalizeKeySegment(const std::u16string &input) {
|
||||
std::u16string result;
|
||||
@@ -75,20 +75,20 @@ std::u16string canonicalizeKeySegment(LPCWSTR input) {
|
||||
}
|
||||
|
||||
void initializePredefinedHandlesLocked() {
|
||||
if (predefinedHandlesInitialized) {
|
||||
if (g_predefinedHandlesInitialized) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < kPredefinedKeyCount; ++i) {
|
||||
predefinedHandles[i].canonicalPath = canonicalizeKeySegment(std::u16string(kPredefinedKeyInfos[i].name));
|
||||
predefinedHandles[i].predefined = true;
|
||||
g_predefinedHandles[i].canonicalPath = canonicalizeKeySegment(std::u16string(kPredefinedKeyInfos[i].name));
|
||||
g_predefinedHandles[i].predefined = true;
|
||||
}
|
||||
predefinedHandlesInitialized = true;
|
||||
g_predefinedHandlesInitialized = true;
|
||||
}
|
||||
|
||||
RegistryKeyHandleData *predefinedHandleForValue(uintptr_t value) {
|
||||
for (size_t i = 0; i < kPredefinedKeyCount; ++i) {
|
||||
if (kPredefinedKeyInfos[i].value == value) {
|
||||
return &predefinedHandles[i];
|
||||
return &g_predefinedHandles[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@@ -121,20 +121,110 @@ bool isPredefinedKeyHandle(HKEY hKey) {
|
||||
}
|
||||
|
||||
void ensureRegistryInitializedLocked() {
|
||||
if (registryInitialized) {
|
||||
if (g_registryInitialized) {
|
||||
return;
|
||||
}
|
||||
initializePredefinedHandlesLocked();
|
||||
for (size_t i = 0; i < kPredefinedKeyCount; ++i) {
|
||||
existingKeys.insert(predefinedHandles[i].canonicalPath);
|
||||
for (auto &g_predefinedHandle : g_predefinedHandles) {
|
||||
g_existingKeys.insert(g_predefinedHandle.canonicalPath);
|
||||
}
|
||||
registryInitialized = true;
|
||||
g_registryInitialized = true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace advapi32 {
|
||||
|
||||
LSTATUS WIN_FUNC RegCreateKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LPWSTR lpClass, DWORD dwOptions,
|
||||
REGSAM samDesired, void *lpSecurityAttributes, PHKEY phkResult,
|
||||
LPDWORD lpdwDisposition) {
|
||||
std::string subKeyString = lpSubKey ? wideStringToString(lpSubKey) : std::string("(null)");
|
||||
std::string classString = lpClass ? wideStringToString(lpClass) : std::string("(null)");
|
||||
DEBUG_LOG("RegCreateKeyExW(%p, %s, %u, %s, 0x%x, 0x%x, %p, %p, %p)\n", hKey, subKeyString.c_str(), Reserved,
|
||||
classString.c_str(), dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
|
||||
(void)lpClass;
|
||||
(void)lpSecurityAttributes;
|
||||
if (!phkResult) {
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
*phkResult = nullptr;
|
||||
if (Reserved != 0) {
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
if (dwOptions != 0) {
|
||||
DEBUG_LOG("RegCreateKeyExW: unsupported options 0x%x\n", dwOptions);
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
REGSAM sanitizedAccess = samDesired & ~(KEY_WOW64_64KEY | KEY_WOW64_32KEY);
|
||||
if (sanitizedAccess != samDesired) {
|
||||
DEBUG_LOG("RegCreateKeyExW: ignoring WOW64 access mask 0x%x\n", samDesired ^ sanitizedAccess);
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(g_registryMutex);
|
||||
ensureRegistryInitializedLocked();
|
||||
RegistryKeyHandleData *baseHandle = handleDataFromHKeyLocked(hKey);
|
||||
if (!baseHandle) {
|
||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||
return ERROR_INVALID_HANDLE;
|
||||
}
|
||||
std::u16string targetPath = baseHandle->canonicalPath;
|
||||
bool targetingBase = true;
|
||||
if (lpSubKey && lpSubKey[0] != 0) {
|
||||
std::u16string subComponent = canonicalizeKeySegment(lpSubKey);
|
||||
if (!subComponent.empty()) {
|
||||
targetingBase = false;
|
||||
if (!targetPath.empty()) {
|
||||
targetPath.push_back(u'\\');
|
||||
}
|
||||
targetPath.append(subComponent);
|
||||
}
|
||||
}
|
||||
if (targetPath.empty()) {
|
||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||
return ERROR_INVALID_HANDLE;
|
||||
}
|
||||
bool existed = g_existingKeys.find(targetPath) != g_existingKeys.end();
|
||||
if (!existed) {
|
||||
g_existingKeys.insert(targetPath);
|
||||
}
|
||||
if (lpdwDisposition) {
|
||||
*lpdwDisposition = existed ? REG_OPENED_EXISTING_KEY : REG_CREATED_NEW_KEY;
|
||||
}
|
||||
if (targetingBase) {
|
||||
*phkResult = hKey;
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
auto *handleData = new RegistryKeyHandleData;
|
||||
handleData->canonicalPath = targetPath;
|
||||
handleData->predefined = false;
|
||||
auto handle = handles::allocDataHandle({handles::TYPE_REGISTRY_KEY, handleData, sizeof(*handleData)});
|
||||
*phkResult = reinterpret_cast<HKEY>(handle);
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
LSTATUS WIN_FUNC RegCreateKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions,
|
||||
REGSAM samDesired, void *lpSecurityAttributes, PHKEY phkResult,
|
||||
LPDWORD lpdwDisposition) {
|
||||
DEBUG_LOG("RegCreateKeyExA(%p, %s, %u, %s, 0x%x, 0x%x, %p, %p, %p)\n", hKey, lpSubKey ? lpSubKey : "(null)",
|
||||
Reserved, lpClass ? lpClass : "(null)", dwOptions, samDesired, lpSecurityAttributes, phkResult,
|
||||
lpdwDisposition);
|
||||
std::vector<uint16_t> subKeyWideStorage;
|
||||
if (lpSubKey) {
|
||||
subKeyWideStorage = stringToWideString(lpSubKey);
|
||||
}
|
||||
std::vector<uint16_t> classWideStorage;
|
||||
if (lpClass) {
|
||||
classWideStorage = stringToWideString(lpClass);
|
||||
}
|
||||
return RegCreateKeyExW(hKey, lpSubKey ? reinterpret_cast<LPCWSTR>(subKeyWideStorage.data()) : nullptr, Reserved,
|
||||
lpClass ? reinterpret_cast<LPWSTR>(classWideStorage.data()) : nullptr, dwOptions, samDesired,
|
||||
lpSecurityAttributes, phkResult, lpdwDisposition);
|
||||
}
|
||||
|
||||
LSTATUS WIN_FUNC RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult) {
|
||||
std::string subKeyString = lpSubKey ? wideStringToString(lpSubKey) : std::string("(null)");
|
||||
DEBUG_LOG("RegOpenKeyExW(%p, %s, %u, 0x%x, %p)\n", hKey, subKeyString.c_str(), ulOptions, samDesired, phkResult);
|
||||
@@ -155,7 +245,7 @@ LSTATUS WIN_FUNC RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REG
|
||||
DEBUG_LOG("RegOpenKeyExW: ignoring WOW64 access mask 0x%x\n", samDesired ^ sanitizedAccess);
|
||||
}
|
||||
(void)sanitizedAccess;
|
||||
std::lock_guard<std::mutex> lock(registryMutex);
|
||||
std::lock_guard<std::mutex> lock(g_registryMutex);
|
||||
ensureRegistryInitializedLocked();
|
||||
RegistryKeyHandleData *baseHandle = handleDataFromHKeyLocked(hKey);
|
||||
if (!baseHandle) {
|
||||
@@ -176,7 +266,7 @@ LSTATUS WIN_FUNC RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REG
|
||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||
return ERROR_INVALID_HANDLE;
|
||||
}
|
||||
if (existingKeys.find(targetPath) == existingKeys.end()) {
|
||||
if (g_existingKeys.find(targetPath) == g_existingKeys.end()) {
|
||||
wibo::lastError = ERROR_FILE_NOT_FOUND;
|
||||
return ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
@@ -208,6 +298,93 @@ LSTATUS WIN_FUNC RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGS
|
||||
return RegOpenKeyExW(hKey, widePtr, ulOptions, samDesired, phkResult);
|
||||
}
|
||||
|
||||
LSTATUS WIN_FUNC RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, BYTE *lpData,
|
||||
LPDWORD lpcbData) {
|
||||
std::string valueName = lpValueName ? wideStringToString(lpValueName) : std::string("(default)");
|
||||
DEBUG_LOG("RegQueryValueExW(%p, %s, %p, %p, %p, %p)\n", hKey, valueName.c_str(), lpReserved, lpType, lpData,
|
||||
lpcbData);
|
||||
if (lpReserved) {
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
if (lpcbData) {
|
||||
*lpcbData = 0;
|
||||
}
|
||||
if (lpType) {
|
||||
*lpType = 0;
|
||||
}
|
||||
(void)hKey;
|
||||
(void)lpData;
|
||||
wibo::lastError = ERROR_FILE_NOT_FOUND;
|
||||
return ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
LSTATUS WIN_FUNC RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, BYTE *lpData,
|
||||
LPDWORD lpcbData) {
|
||||
DEBUG_LOG("RegQueryValueExA(%p, %s, %p, %p, %p, %p)\n", hKey, lpValueName ? lpValueName : "(null)", lpReserved,
|
||||
lpType, lpData, lpcbData);
|
||||
std::vector<uint16_t> valueWideStorage;
|
||||
if (lpValueName) {
|
||||
valueWideStorage = stringToWideString(lpValueName);
|
||||
}
|
||||
return RegQueryValueExW(hKey, lpValueName ? reinterpret_cast<LPCWSTR>(valueWideStorage.data()) : nullptr,
|
||||
lpReserved, lpType, lpData, lpcbData);
|
||||
}
|
||||
|
||||
LSTATUS WIN_FUNC RegEnumKeyExW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, LPDWORD lpcchName, LPDWORD lpReserved,
|
||||
LPWSTR lpClass, LPDWORD lpcchClass, FILETIME *lpftLastWriteTime) {
|
||||
DEBUG_LOG("RegEnumKeyExW(%p, %u, %p, %p, %p, %p, %p, %p)\n", hKey, dwIndex, lpName, lpcchName, lpReserved, lpClass,
|
||||
lpcchClass, lpftLastWriteTime);
|
||||
(void)hKey;
|
||||
(void)dwIndex;
|
||||
if (lpReserved) {
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
if (lpcchName) {
|
||||
*lpcchName = 0;
|
||||
}
|
||||
if (lpName && lpcchName && *lpcchName > 0) {
|
||||
lpName[0] = 0;
|
||||
}
|
||||
if (lpClass && lpcchClass && *lpcchClass > 0) {
|
||||
lpClass[0] = 0;
|
||||
}
|
||||
if (lpcchClass) {
|
||||
*lpcchClass = 0;
|
||||
}
|
||||
(void)lpftLastWriteTime;
|
||||
wibo::lastError = ERROR_NO_MORE_ITEMS;
|
||||
return ERROR_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
LSTATUS WIN_FUNC RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcchName, LPDWORD lpReserved,
|
||||
LPSTR lpClass, LPDWORD lpcchClass, FILETIME *lpftLastWriteTime) {
|
||||
DEBUG_LOG("RegEnumKeyExA(%p, %u, %p, %p, %p, %p, %p, %p)\n", hKey, dwIndex, lpName, lpcchName, lpReserved, lpClass,
|
||||
lpcchClass, lpftLastWriteTime);
|
||||
(void)hKey;
|
||||
(void)dwIndex;
|
||||
if (lpReserved) {
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
if (lpcchName) {
|
||||
*lpcchName = 0;
|
||||
}
|
||||
if (lpName && lpcchName && *lpcchName > 0) {
|
||||
lpName[0] = '\0';
|
||||
}
|
||||
if (lpClass && lpcchClass && *lpcchClass > 0) {
|
||||
lpClass[0] = '\0';
|
||||
}
|
||||
if (lpcchClass) {
|
||||
*lpcchClass = 0;
|
||||
}
|
||||
(void)lpftLastWriteTime;
|
||||
wibo::lastError = ERROR_NO_MORE_ITEMS;
|
||||
return ERROR_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
LSTATUS WIN_FUNC RegCloseKey(HKEY hKey) {
|
||||
DEBUG_LOG("RegCloseKey(%p)\n", hKey);
|
||||
if (isPredefinedKeyHandle(hKey)) {
|
||||
|
||||
Reference in New Issue
Block a user