Question

I am trying to use HeapAlloc() to allocate a buffer used by SetupDiGetDeviceRegistryProperty().

Inside GetDeviceInformation() I have:

HANDLE hHeap = GetProcessHeap();

while (SetupDiEnumDeviceInfo(DeviceInfoSet, MemberIndex++, DeviceInfoData)) 
{
    DWORD DataT;
    LPTSTR buffer = NULL;
    DWORD buffersize = 0;
    // port of device
    DWORD portnum = 0;

    GetRegistryProperty(DeviceInfoSet, DeviceInfoData, SPDRP_FRIENDLYNAME, 
         &DataT, buffer, &buffersize, &buffersize);

    if (!buffer) 
    {
        cerr << "Null Ptr!" << endl;
        exit(1);
    }
    // Do stuff, uninstall device


    if (buffer) HeapFree(hHeap, NULL, buffer); 

    }
}

And inside GetRegistryProperty() I have:

void GetRegistryProperty(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, 
    DWORD Property, PDWORD DataT, LPTSTR buffer, PDWORD buffersize, PDWORD size)
{


    HANDLE hHeap = GetProcessHeap();

    while (!SetupDiGetDeviceRegistryProperty(
        DeviceInfoSet,
        DeviceInfoData,
        Property, //SPDRP_FRIENDLYNAME or SPDRP_CLASS
        DataT, //&DataT
        (PBYTE)buffer,
        *buffersize,
        size)) //&buffersize
    {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {
            // Change the buffer size.
            if (buffer) HeapFree(hHeap, NULL, buffer); 

            // Double the size to avoid problems on 
            // W2k MBCS systems per KB 888609. 
            buffer = (LPTSTR)HeapAlloc(hHeap, HEAP_ZERO_MEMORY |
                HEAP_GENERATE_EXCEPTIONS, *buffersize * 2);
        }
        else
        {
            // error handling
            break;
        }
    }
}

HeapAlloc() works as expected (the buffer is filled with the property) until GetRegistryProperty() returns. At this point, the buffer is always NULL. Is this also expected? How can I return a char * pointing to an array that lives past the life of the function that created it? I assume that I don't understand how HeapAlloc() works.

The reason I have it in a separate function is that I would like to call GetRegistryProperty() multiple times with different DWORD Propertys. Before I moved the code to a separate function it worked perfectly.

Était-ce utile?

La solution

Pass the buffer by reference (note the LPTSTR&) :

void GetRegistryProperty(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, 
    DWORD Property, PDWORD DataT, LPTSTR& buffer, PDWORD buffersize, PDWORD size)

Autres conseils

You are passing buffer by value, so in GetRegistryProperty, when you reassign it, you simply overwrite the copy of the pointer in GetRegistryProperty.

Change the signature of GetRegistryProperty to:

void GetRegistryProperty(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD DataT, LPTSTR& buffer, PDWORD buffersize, PDWORD size)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top