I am trying to use the RegGetValueA()
from the Windows API , but so far I've been unable to get any results from it. At best, I get a "file not found" error, and at worst it crashes hard without any error messages at all.
Below is the current code I have; I'm not sure what is and isn't relevant, and what might be causing the problem or not. I've only got a smidge of C knowledge, so please try to keep it simple.
ffi.cdef([[
typedef void * HKEY;
typedef HKEY * PHKEY;
typedef unsigned long DWORD;
int RegGetValueA(HKEY handle, const char* path, const char* value, int filter_flags, void* unused, char *result, DWORD* size);
]])
local size = ffi.new('DWORD[1]')
size = 1024
local data = ffi.new('char['..size..']')
local dptr = ffi.cast('char*', data)
local lenptr = ffi.cast('DWORD*', size)
test = reg.RegGetValueA(ffi.cast("HKEY", ffi.cast("uintptr_t",0x80000002)), "SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\CereVoice Heather 5.0.1", "CLSID", 0x0000ffff, nil, dptr, lenptr)
When you use ffi.new
, what you get is a pointer variable, and you assign the pointer to 1024
, and then use ffi.cast
to convert to DWORD *
, which causes an access address conflict when calling RegGetValueA
, so the program crashes.
You only need to modify the code as follows:
local ffi = require("ffi")
ffi.cdef([[
typedef void * HKEY;
typedef HKEY * PHKEY;
typedef unsigned long DWORD;
int RegGetValueA(HKEY handle, const char* path, const char* value, int
filter_flags, void* unused, char *result, DWORD* size);
]])
local size = 1024
local data = ffi.new('char['..size..']')
local dptr = ffi.cast('char*', data)
local lenptr = ffi.new('DWORD[1]', size)
local test = ffi.C.RegGetValueA(ffi.cast("HKEY", ffi.cast("uintptr_t",0x80000002)), "SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\CereVoice Heather 5.0.1", "CLSID", 0x0000ffff, nil, dptr, lenptr)
print(test)
print(ffi.string(dptr))
I get a "file not found" error
This means "registry key not found".
There are two different registries in 64-bit Windows, you should try reading from both of them:
local ffi = require'ffi'
ffi.cdef"int RegGetValueA(uintptr_t, const char*, const char*, uint32_t, void*, char*, uint32_t*);"
local size = 1024
local pcbData = ffi.new'uint32_t[1]'
local pvData = ffi.new('char[?]', size)
local RRF_SUBKEY_WOW6464KEY = 0x00010000
local RRF_SUBKEY_WOW6432KEY = 0x00020000
for _, WOW64_flag in ipairs{RRF_SUBKEY_WOW6464KEY, RRF_SUBKEY_WOW6432KEY} do
pcbData[0] = size
local errcode = ffi.C.RegGetValueA(
0x80000002, -- HKLM
"SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\MS-Anna-1033-20-DSK",
"CLSID",
0x0000ffff + WOW64_flag,
nil,
pvData,
pcbData
)
if errcode == 0 then
break
end
end
print(ffi.string(pvData))
User contributions licensed under CC BY-SA 3.0