Search code examples
winapiluaffilove2dluajit

RegGetValueA hard crashing application using luajit ffi


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)

Solution

  • 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))