VC++ HeapAlloc внутри функции дает нулевой указатель

Я пытаюсь использовать HeapAlloc() выделить буфер, используемый SetupDiGetDeviceRegistryProperty(),

внутри GetDeviceInformation() Я имею:

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

    }
}

И внутри GetRegistryProperty() Я имею:

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() работает как положено (буфер заполнен свойством) до GetRegistryProperty() возвращается. На этом этапе буфер всегда равен NULL. Это тоже ожидается? Как я могу вернуть char *, указывающий на массив, который живет после жизни функции, которая его создала? Я предполагаю, что я не понимаю, как работает HeapAlloc().

Причина, по которой у меня есть отдельная функция, заключается в том, что я хотел бы вызвать GetRegistryProperty() несколько раз с разными DWORD Propertys. До того, как я переместил код в отдельную функцию, он работал отлично.

2 ответа

Решение

Пройти buffer по ссылке (обратите внимание на LPTSTR &):

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

Вы проходите buffer по значению, поэтому в GetRegistryProperty при его переназначении вы просто перезаписываете копию указателя в GetRegistryProperty.

Измените подпись GetRegistryProperty на:

void GetRegistryProperty(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD DataT, LPTSTR& buffer, PDWORD buffersize, PDWORD size)
Другие вопросы по тегам