diff --git a/Source/Windows/Common/WinAPI/Misc.cpp b/Source/Windows/Common/WinAPI/Misc.cpp index d85b60e8f..970af12dc 100644 --- a/Source/Windows/Common/WinAPI/Misc.cpp +++ b/Source/Windows/Common/WinAPI/Misc.cpp @@ -122,3 +122,65 @@ DLLEXPORT_FUNC(DWORD, GetLastError, ()) { DLLEXPORT_FUNC(void, SetLastError, (DWORD dwErrCode)) { GetCurrentTEB()->LastErrorValue = dwErrCode; } + +DLLEXPORT_FUNC(LONG, RegOpenKeyExA, (HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)) { + if (hKey != HKEY_LOCAL_MACHINE) { + UNIMPLEMENTED(); + } + + ScopedUnicodeString RootKey {"\\Registry\\Machine"}; + OBJECT_ATTRIBUTES ObjAttributes; + InitializeObjectAttributes(&ObjAttributes, &*RootKey, OBJ_CASE_INSENSITIVE, nullptr, nullptr); + HKEY HKLM; + NTSTATUS Status = NtOpenKeyEx(reinterpret_cast(&HKLM), MAXIMUM_ALLOWED, &ObjAttributes, 0); + if (Status) { + return RtlNtStatusToDosError(Status); + } + + ScopedUnicodeString SubKey {lpSubKey}; + InitializeObjectAttributes(&ObjAttributes, &*SubKey, OBJ_CASE_INSENSITIVE, reinterpret_cast(HKLM), nullptr); + Status = NtOpenKeyEx(reinterpret_cast(phkResult), samDesired, &ObjAttributes, ulOptions); + NtClose(HKLM); + return RtlNtStatusToDosError(Status); +} + +DLLEXPORT_FUNC(LONG, RegGetValueA, (HKEY hKey, LPCSTR lpSubKey, LPCSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)) { + if (lpSubKey || dwFlags) { + UNIMPLEMENTED(); + } + + ScopedUnicodeString ValueName {lpValue}; + + union { + KEY_VALUE_PARTIAL_INFORMATION Info; + uint8_t Buf[512]; + } Data; + ULONG OutSize; + NTSTATUS Status = NtQueryValueKey(hKey, &*ValueName, KeyValuePartialInformation, &Data.Info, sizeof(Data), &OutSize); + if (Status) { + return RtlNtStatusToDosError(Status); + } + + if (pdwType) { + *pdwType = Data.Info.Type; + } + + if (pvData) { + if (*pcbData < Data.Info.DataLength) { + *pcbData = Data.Info.DataLength; + return ERROR_MORE_DATA; + } + + memcpy(pvData, &Data.Info.Data, Data.Info.DataLength); + } + + if (pcbData) { + *pcbData = Data.Info.DataLength; + } + + return ERROR_SUCCESS; +} + +DLLEXPORT_FUNC(LONG, RegCloseKey, (HKEY hKey)) { + return RtlNtStatusToDosError(NtClose(hKey)); +} diff --git a/Source/Windows/include/winternl.h b/Source/Windows/include/winternl.h index fdd6cee30..d9dca52f9 100644 --- a/Source/Windows/include/winternl.h +++ b/Source/Windows/include/winternl.h @@ -415,6 +415,22 @@ typedef enum _MEMORY_INFORMATION_CLASS { #endif } MEMORY_INFORMATION_CLASS; +typedef enum _KEY_VALUE_INFORMATION_CLASS { + KeyValueBasicInformation, + KeyValueFullInformation, + KeyValuePartialInformation, + KeyValueFullInformationAlign64, + KeyValuePartialInformationAlign64, + KeyValueLayerInformation, +} KEY_VALUE_INFORMATION_CLASS; + +typedef struct _KEY_VALUE_PARTIAL_INFORMATION { + ULONG TitleIndex; + ULONG Type; + ULONG DataLength; + UCHAR Data[1]; +} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION; + NTSTATUS WINAPIV DbgPrint(LPCSTR fmt, ...); NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE); NTSTATUS WINAPI LdrGetDllHandle(LPCWSTR, ULONG, const UNICODE_STRING*, HMODULE*); @@ -426,8 +442,10 @@ NTSTATUS WINAPI NtFlushInstructionCache(HANDLE, LPCVOID, SIZE_T); NTSTATUS WINAPI NtFreeVirtualMemory(HANDLE, PVOID*, SIZE_T*, ULONG); NTSTATUS WINAPI NtGetContextThread(HANDLE, CONTEXT*); ULONG WINAPI NtGetCurrentProcessorNumber(void); +NTSTATUS WINAPI NtOpenKeyEx(PHANDLE, ACCESS_MASK, const OBJECT_ATTRIBUTES*, ULONG); NTSTATUS WINAPI NtProtectVirtualMemory(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG*); NTSTATUS WINAPI NtQueryAttributesFile(const OBJECT_ATTRIBUTES*, FILE_BASIC_INFORMATION*); +NTSTATUS WINAPI NtQueryValueKey(HANDLE, const UNICODE_STRING*, KEY_VALUE_INFORMATION_CLASS, void*, DWORD, DWORD*); NTSTATUS WINAPI NtQueryVirtualMemory(HANDLE, LPCVOID, MEMORY_INFORMATION_CLASS, PVOID, SIZE_T, SIZE_T*); NTSTATUS WINAPI NtReadFile(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, PLARGE_INTEGER, PULONG); NTSTATUS WINAPI NtSetContextThread(HANDLE, const CONTEXT*);