c++nvidianvapi

Problems retrieving the Global Profile settings (shown in the Nvidia Control Panel) with NVAPI SDK


I want to use NVIDIA's NVAPI SDK to retrieve all the settings exposed in the NVIDIA Control Panel's 3D Settings' Global profile.

enter image description here

The reference documentation is here: NVAPI Driver Settings (DRS) APIs

Source

Here is what I have so far, mostly basing myself on samples I've found around the web:

#include <Windows.h>
#include <string>
#include "nvapi.h"
#include "NvApiDriverSettings.h"

NvDRSSessionHandle _session;
NvDRSProfileHandle _profile;

int main()
{
    if (NvAPI_Initialize() != NVAPI_OK)
        throw std::runtime_error("NvAPI: NvAPI can't be initialized");

    if (NvAPI_DRS_CreateSession(&_session) != NVAPI_OK)
        throw std::runtime_error("NvAPI: Can't create NvAPI session");
    if (NvAPI_DRS_LoadSettings(_session) != NVAPI_OK)
        throw std::runtime_error("NvAPI: Can't load system settings");

    if (NvAPI_DRS_GetCurrentGlobalProfile(_session, &_profile) != NVAPI_OK)
        throw std::runtime_error("NvAPI: Can't get global profile");

    NVDRS_PROFILE profileInformation = {0};
    profileInformation.version = NVDRS_PROFILE_VER;
    if (NvAPI_DRS_GetProfileInfo(_session, _profile, &profileInformation) != NVAPI_OK)
        throw std::runtime_error("NvAPI: Can't get current global profile information");

    if(profileInformation.numOfSettings> 0)
    {
        NVDRS_SETTING* setArray = new NVDRS_SETTING[profileInformation.numOfSettings];
        NvU32 numSetRead = profileInformation.numOfSettings,i;
        setArray[0].version = NVDRS_SETTING_VER;
        if (NvAPI_DRS_EnumSettings(_session, _profile, 0, &numSetRead, setArray) != NVAPI_OK)
            throw std::runtime_error("NvAPI: Can't get profile setting enum");

        for(i=0; i<numSetRead; i++)
        {
            if(setArray[i].settingLocation!=NVDRS_CURRENT_PROFILE_LOCATION)
            {
                continue;
            }
            NvAPI_DRS_GetSettingNameFromId(setArray[i].settingId, &setArray[i].settingName);
            wprintf(L"Setting Name: %s\n", setArray[i].settingName);
            printf("Setting ID: %X\n", setArray[i].settingId);
            printf("Predefined? : %d\n", setArray[i].isCurrentPredefined);
            switch(setArray[i].settingType)
            {
            case NVDRS_DWORD_TYPE:
                printf("Setting Value: %X\n", setArray[i].u32CurrentValue);
                break;
            case NVDRS_BINARY_TYPE:
                {
                    unsigned int len;
                    printf("Setting Binary (length=%d) :", setArray[i].binaryCurrentValue.valueLength);
                    for(len=0; len<setArray[i].binaryCurrentValue.valueLength; len++)
                    {
                        printf(" %02x", setArray[i].binaryCurrentValue.valueData[len]);
                    }
                    printf("\n");
                }
                break;
            case NVDRS_WSTRING_TYPE:
                wprintf(L"Setting Value: %s\n", setArray[i].wszCurrentValue);
                break;
            }
        }
    }
    printf("\n");
    // Clean up
    NvAPI_DRS_DestroySession(_session);
    _session = 0;
    return 0;
}

Console Output

This is the output I am currently getting:

Setting Name: Vertical Sync Tear Control
Setting ID: 5A375C
Predefined? : 0
Setting Value: 96861077
Setting Name: Vertical Sync
Setting ID: A879CF
Predefined? : 0
Setting Value: 8416747
Setting Name: ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
Setting ID: 80303A19
Predefined? : 1
Setting Value: 1
Setting Name: ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
Setting ID: 80857A28
Predefined? : 1
Setting Value: 1
Setting Name: ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
Setting ID: 809D5F60
Predefined? : 1
Setting Value: 1

Problem

Some Setting names are not displayed correctly (???...), and most seem to be missing (Ambient Occlusion, Anisotropy, Power management, etc.).

Am I getting the wrong profile or is it perhaps initialized incorrectly?

Related Questions

Some questions:


Solution

  • Your array has uninitialized memory

    NVDRS_SETTING* setArray = new NVDRS_SETTING[profileInformation.numOfSettings];
    

    and that means you can find any sort of data in it (hence the invalid strings you're printing).

    Either consider zero-initializing it

    NVDRS_SETTING*setArray = new NVDRS_SETTING[profileInformation.numOfSettings];
    // Remember `setArray` is a pointer
    memset(setArray, 0, sizeof(*setArray) * profileInformation.numOfSettings);
    

    or use a std::vector which, in this case, will zero-initialize your structs as well (although having an explicit constructor to do the job would have made things easier and more reliable).

    Finally consider skipping invalid entries, you might want to skip invalid named entries as well (that you can now detect reliably)

    if (setArray[i].settingName[0] == 0x00)
      continue;
    

    From the NVAPI guide

    The Base Profile is a profile that always exists and is not associated with a specific application. The settings in the Base Profile are applied to all processes on the system automatically.

    A profile with no applications is called a Global Profile. The settings from a Global Profile are applied to all processes on the system, but only if that profile is selected to be the Current Global Profile in the system.

    so in your case it might be, but not if you set a different current global profile (cfr. NvAPI_DRS_SetCurrentGlobalProfile).

    Mostly, many other advanced settings are hidden in the control panel but accessible via code and/or other advanced tools. An even deeper layer could be dabbling with undocumented functions but you might break a lot of things if you don't know what you're doing.