Search code examples
c++windowsvisual-studio-2015writefile

Write RegQueryValueEx values to a file with WriteFile fails


I am editing a small program to get some info from the registry, print it to console and then write it to file.

I can print to console with _tprintf correctly.

I created a handle "myfile" to a new file, writing "buffer" to the file is not successful "partial data are written" and I do not know why, I think it is related to "BYTE* buffer = new BYTE[cbMaxValueData];", but I do not know how to fix it.

void QueryKey(HKEY hkey)
{
TCHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey name
DWORD    cbName;                   // size of name string 
TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name 
DWORD    cchClassName = MAX_PATH;  // size of class string 
DWORD    cSubKeys = 0;               // number of subkeys 
DWORD    cbMaxSubKey;              // longest subkey size 
DWORD    cchMaxClass;              // longest class string 
DWORD    cValues;              // number of values for key 
DWORD    cchMaxValue;          // longest value name 
DWORD    cbMaxValueData;       // longest value data 
DWORD    cbSecurityDescriptor; // size of security descriptor 
FILETIME ftLastWriteTime;      // last write time 

DWORD i, retCode;

TCHAR  achValue[MAX_VALUE_NAME];

// Get the class name and the value count. 
retCode = RegQueryInfoKey(
    hkey,                    // key handle 
    achClass,                // buffer for class name 
    &cchClassName,           // size of class string 
    NULL,                    // reserved 
    &cSubKeys,               // number of subkeys 
    &cbMaxSubKey,            // longest subkey size 
    &cchMaxClass,            // longest class string 
    &cValues,                // number of values for this key 
    &cchMaxValue,            // longest value name 
    &cbMaxValueData,         // longest value data 
    &cbSecurityDescriptor,   // security descriptor 
    &ftLastWriteTime);       // last write time 

                             // Enumerate the subkeys, until RegEnumKeyEx fails.

if (cSubKeys)
{
    printf("\nNumber of subkeys: %d\n", cSubKeys);

    for (i = 0; i<cSubKeys; i++)
    {
        cbName = MAX_KEY_LENGTH;
        retCode = RegEnumKeyEx(hkey, i,
            achKey,
            &cbName,
            NULL,
            NULL,
            NULL,
            &ftLastWriteTime);
        if (retCode == ERROR_SUCCESS)
        {
            _tprintf(TEXT("(%d) %s\n"), i + 1, achKey);
        }
    }
}

// Enumerate the key values. 

BYTE* buffer = new BYTE[cbMaxValueData];


ZeroMemory(buffer, cbMaxValueData);


if (cValues)
{
    printf("\nNumber of values: %d\n", cValues);

    for (i = 0, retCode = ERROR_SUCCESS; i<cValues; i++)
    {
        cchValue = MAX_VALUE_NAME;
        achValue[0] = '\0';
        retCode = RegEnumValue(hkey, i,
            achValue,
            &cchValue,
            NULL,
            NULL,
            NULL,
            NULL);

        if (retCode == ERROR_SUCCESS)
        {
            DWORD lpData = cbMaxValueData;
            buffer[0] = '\0';

            RegQueryValueEx(hkey, achValue, 0, NULL, buffer, &lpData);

        }
        _tprintf(TEXT("(%d) %s : %s\n"), i + 1, achValue, buffer);

        WriteFile(myfile, buffer, sizeof(buffer), NULL, NULL);


    }
}
}

Solution

  • sizeof(buffer) is not necessarily the size of the data you want to write into the file. If the string in the buffer is shorter than the buffer size, you will be writing garbage data after the string length. Instead, write lpData as the write length.

    EDIT: As Hans Passant pointed out, buffer is a pointer and not an array, so sizeof(buffer) is certainly far too small to be the length of your string.