-1

There are various variations of this question relating to c++ but I'm trying use registry functions in C. I know that includes , so why is it not seeing RegGetValue(). Is it exclusive to C++? Is there a way to use it in C?

This is some code found that I tried to use to test what would be displayed.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <Windows.h>
#include <errno.h>


#define BUFFER  8192

int main()
{

char value[255];
    DWORD BufferSize = BUFFER;
    RegGetValue(HKEY_LOCAL_MACHINE, 
        "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 
        "RegisteredOwner", 
        RRF_RT_ANY | RRF_SUBKEY_WOW6464KEY, 
        NULL, 
        (PVOID)&value, 
        &BufferSize);
    printf("\n%s\n", value);
    system("pause");

    return 0;
}

I compiled like this this

gcc -Wall RegistryParser.c -o RegistryParser.exe

And I get this warning and errors

RegistryParser.c: In function 'main': RegistryParser.c:26:2: warning: implicit declaration of function 'RegGetValue' [-Wimplicit-function-declaration] RegGetValue(HKEY_LOCAL_MACHINE, ^~~~~~~~~~~

RegistryParser.c:29:3: error: 'RRF_RT_ANY' undeclared (first use in this function) RRF_RT_ANY | RRF_SUBKEY_WOW6464KEY, ^~~~~~~~~~ RegistryParser.c:29:3: note: each undeclared identifier is reported only once for each function it appears in

RegistryParser.c:29:16: error: 'RRF_SUBKEY_WOW6464KEY' undeclared (first use in this function) RRF_RT_ANY | RRF_SUBKEY_WOW6464KEY, ^~~~~~~~~~~~~~~~~~~~~

1 Answers1

0

Before I answer my own question this was just a hack I did to get it working, it might break later

I figured out what was my issue. It was with my compiler. The short and sweet is I updated C:\MinGW\include folder by

[1] going to https://sourceforge.net/projects/mingw-w64/files/

[2] clicking the MinGW-W64-install.exe. Saving it and running it

[3] And then copied the 'include' folder from C:\Program Files\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\x86_64-w64-mingw32\include (that's where default location was for me) to C:\MinGW overwritten all the headers (explanation to this foolishness in the details section)

Details

I thought my code in the my question would work because information at https://learn.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-reggetvaluew . I was looking at the header in the Windows Kits C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\Windows.h which has the code block

#if !defined(_MAC) || defined(_WIN32REG)
#include <winreg.h>
#endif

and C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\winreg.h has the code

//
// RRF - Registry Routine Flags (for RegGetValue)
//

#define RRF_RT_REG_NONE        0x00000001  // restrict type to REG_NONE      (other data types will not return ERROR_SUCCESS)
#define RRF_RT_REG_SZ          0x00000002  // restrict type to REG_SZ        (other data types will not return ERROR_SUCCESS) (automatically converts REG_EXPAND_SZ to REG_SZ unless RRF_NOEXPAND is specified)
#define RRF_RT_REG_EXPAND_SZ   0x00000004  // restrict type to REG_EXPAND_SZ (other data types will not return ERROR_SUCCESS) (must specify RRF_NOEXPAND or RegGetValue will fail with ERROR_INVALID_PARAMETER)
#define RRF_RT_REG_BINARY      0x00000008  // restrict type to REG_BINARY    (other data types will not return ERROR_SUCCESS)
#define RRF_RT_REG_DWORD       0x00000010  // restrict type to REG_DWORD     (other data types will not return ERROR_SUCCESS)
#define RRF_RT_REG_MULTI_SZ    0x00000020  // restrict type to REG_MULTI_SZ  (other data types will not return ERROR_SUCCESS)
#define RRF_RT_REG_QWORD       0x00000040  // restrict type to REG_QWORD     (other data types will not return ERROR_SUCCESS)

#define RRF_RT_DWORD           (RRF_RT_REG_BINARY | RRF_RT_REG_DWORD) // restrict type to *32-bit* RRF_RT_REG_BINARY or RRF_RT_REG_DWORD (other data types will not return ERROR_SUCCESS)
#define RRF_RT_QWORD           (RRF_RT_REG_BINARY | RRF_RT_REG_QWORD) // restrict type to *64-bit* RRF_RT_REG_BINARY or RRF_RT_REG_DWORD (other data types will not return ERROR_SUCCESS)
#define RRF_RT_ANY             0x0000ffff                             // no type restriction

#if (_WIN32_WINNT >= _WIN32_WINNT_WINTHRESHOLD)
#define RRF_SUBKEY_WOW6464KEY  0x00010000  // when opening the subkey (if provided) force open from the 64bit location (only one SUBKEY_WOW64* flag can be set or RegGetValue will fail with ERROR_INVALID_PARAMETER)
#define RRF_SUBKEY_WOW6432KEY  0x00020000  // when opening the subkey (if provided) force open from the 32bit location (only one SUBKEY_WOW64* flag can be set or RegGetValue will fail with ERROR_INVALID_PARAMETER)
#define RRF_WOW64_MASK         0x00030000
#endif

#define RRF_NOEXPAND           0x10000000  // do not automatically expand environment strings if value is of type REG_EXPAND_SZ
#define RRF_ZEROONFAILURE      0x20000000  // if pvData is not NULL, set content to all zeros on failure

... some more code and then

#if (_WIN32_WINNT >= 0x0502)

WINADVAPI
LSTATUS
APIENTRY
RegGetValueA(
    _In_ HKEY hkey,
    _In_opt_ LPCSTR lpSubKey,
    _In_opt_ LPCSTR lpValue,
    _In_ DWORD dwFlags,
    _Out_opt_ LPDWORD pdwType,
    _When_((dwFlags & 0x7F) == RRF_RT_REG_SZ ||
               (dwFlags & 0x7F) == RRF_RT_REG_EXPAND_SZ ||
               (dwFlags & 0x7F) == (RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ) ||
               *pdwType == REG_SZ ||
               *pdwType == REG_EXPAND_SZ, _Post_z_)
        _When_((dwFlags & 0x7F) == RRF_RT_REG_MULTI_SZ ||
               *pdwType == REG_MULTI_SZ, _Post_ _NullNull_terminated_)
    _Out_writes_bytes_to_opt_(*pcbData,*pcbData) PVOID pvData,
    _Inout_opt_ LPDWORD pcbData
    );

WINADVAPI
LSTATUS
APIENTRY
RegGetValueW(
    _In_ HKEY hkey,
    _In_opt_ LPCWSTR lpSubKey,
    _In_opt_ LPCWSTR lpValue,
    _In_ DWORD dwFlags,
    _Out_opt_ LPDWORD pdwType,
    _When_((dwFlags & 0x7F) == RRF_RT_REG_SZ ||
               (dwFlags & 0x7F) == RRF_RT_REG_EXPAND_SZ ||
               (dwFlags & 0x7F) == (RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ) ||
               *pdwType == REG_SZ ||
               *pdwType == REG_EXPAND_SZ, _Post_z_)
        _When_((dwFlags & 0x7F) == RRF_RT_REG_MULTI_SZ ||
               *pdwType == REG_MULTI_SZ, _Post_ _NullNull_terminated_)
    _Out_writes_bytes_to_opt_(*pcbData,*pcbData) PVOID pvData,
    _Inout_opt_ LPDWORD pcbData
    );

#ifdef UNICODE
#define RegGetValue  RegGetValueW
#else
#define RegGetValue  RegGetValueA
#endif

However since I'm using the MinGW gcc, MinGW uses their own modified headers in there include folder. If you have it saved in the default path C:\MinGW\include . So, it looks at the headers in it's C:\MinGW\include folder and their C:\MinGW\include\winreg.h there does not have the RegGetValue() function.

I would show what was in the original C:\MinGW\include\winreg.hheader but I already overwritten it.

So I then went to get an updated version of MinGW at the website I mentioned earlier and tried to update the Path by follow steps to edit 'system variables". I removed the Path to C:\MinGW\bin to add new paths to

C:\Program Files\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\bin

C:\Program Files\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\x86_64-w64-mingw32\bin

C:\Program Files\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\opt\bin

I still had compile warning and errors, so that's when I thought just but the headers I need in the MinGW\include folder. So I removed the new paths and put back the path to C:\MinGW\bin. And did what I mentioned at the beginning of the post. I had to modify my code and remove the "| RRF_SUBKEY_WOW6464KEY" since that isn't defined in MinGW's winreg.h but everything else is the same and it compiles with no warnings or errors and returns what I expected.

Sorry for the long post.