html资源上的CreateStreamOnHGlobal导致堆损坏

时间:2014-03-11 19:27:01

标签: c++ internet-explorer winapi

我在microsoft visual studio项目中添加了一个html文件作为资源。我打算在我的程序中动态更改它的内容,并使用res://webapp.exe/IDR_HTML导航到它,因此它不会在文件系统中。我做了以下。但CreateStreamOnHGlobal导致堆损坏。我做错了什么?可以通过这种方式修改html资源吗?如果我在我的程序中使用GlobalAlloc和CreateStreamOnHGlobal,我就不会有问题。

//problem code
    // Load current module.
    HMODULE hExe = GetModuleHandle(NULL);
    if (hExe == NULL)
    {
        ATLTRACE2(TEXT("Could not load exe."));
        return -1;
    }


    // Locate the html resource in the .EXE file.
    HRSRC hRes = FindResource(hExe, MAKEINTRESOURCE(IDR_HTML), RT_HTML);
    if (hRes == NULL)
    {
        ATLTRACE2(TEXT("Could not locate dialog box."));
        return -1;
    }

    // Load the html into global memory.
    HGLOBAL hResLoad = LoadResource(hExe, hRes);
    if (hResLoad == NULL)
    {
        ATLTRACE2(TEXT("Could not load html."));
        return -1;
    }

    CComPtr<IStream> spStream;
    HRESULT hr = ::CreateStreamOnHGlobal( hResLoad, TRUE, &spStream );

//heap error displayed 
HEAP[WebApp.exe]: Invalid address specified to RtlGetUserInfoHeap( 00560000, 012844C8 )
Windows has triggered a breakpoint in WebApp.exe.

This may be due to a corruption of the heap, which indicates a bug in WebApp.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while WebApp.exe has focus.

The output window may have more diagnostic information.

//this is fine 
char *acTemp;
    char *acXml = "Hello";
    SIZE_T dwBytes = 256;
    CComPtr<IStream> pDataStream;
    acTemp = (CHAR *) GlobalAlloc (GMEM_FIXED, dwBytes);
    memcpy (acTemp, acXml, dwBytes);
    HRESULT hhr = ::CreateStreamOnHGlobal(acTemp, TRUE, &pDataStream);

1 个答案:

答案 0 :(得分:1)

正如Raymond Chen所说,HGLOBAL返回的LoadResource()不是真正的HGLOBAL,因此您无法将其传递给CreateStreamOnHGlobal()。您必须在内存中复制数据,例如:

CComPtr<IStream> spStream;
HRESULT hr;

HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, SizeofResource(hResLoad));
if (!hMem)
{
    hr = HRESULT_FROM_WIN32(GetLastError());
}
else
{
    LPVOID ptr = GlobalLock(hMem);
    if (ptr)
    {
        memcpy( ptr, LockResource(hResLoad), SizeofResource(hResLoad) );
        GlobalUnlock(hMem);
    }

    hr = CreateStreamOnHGlobal( hMem, TRUE, &spStream );
}

正如documentation建议的那样,您应该考虑使用SHCreateMemStream(),例如:

CComPtr<IStream> spStream = ::SHCreateMemStream( (LPBYTE) LockResource(hResLoad), SizeofResource(hResLoad) );