Fixed bug 5375 - WGI: Fix HSTRING memory leak.

Joel Linn

TLDR; https://godbolt.org/z/43fd8G

Let's deduce this from C++ reference code:

https://docs.microsoft.com/en-us/cpp/cppcx/wrl/how-to-activate-and-use-a-windows-runtime-component-using-wrl?view=msvc-160
At the bottom of the page there is this snippet:
```
int wmain()
{
    /* ... more code ... */

    // Get the domain part of the URI.
    HString domainName;
    hr = uri->get_Domain(domainName.GetAddressOf());
    if (FAILED(hr))
    {
        return PrintError(__LINE__, hr);
    }

    // Print the domain name and return.
    wprintf_s(L"Domain name: %s\n", domainName.GetRawBuffer(nullptr));

    // All smart pointers and RAII objects go out of scope here.
}
```

`HString` is defined in `corewrappers.h` and the call chain for the destructor is:
`~HString() -> Release() -> ::WindowsDeleteString()`

QED
This commit is contained in:
Sam Lantinga 2020-12-09 20:28:51 -08:00
parent d3d2aee7f4
commit 797a6910fd
1 changed files with 12 additions and 10 deletions

View File

@ -184,23 +184,25 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IRawGameController2, (void **)&controller2); hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IRawGameController2, (void **)&controller2);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
HSTRING hString; HMODULE hModule = LoadLibraryA("combase.dll");
if (hModule != NULL) {
typedef PCWSTR (WINAPI *WindowsGetStringRawBuffer_t)(HSTRING string, UINT32 *length);
typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string);
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_get_DisplayName(controller2, &hString); WindowsGetStringRawBuffer_t WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)GetProcAddress(hModule, "WindowsGetStringRawBuffer");
if (SUCCEEDED(hr)) { WindowsDeleteString_t WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString");
HMODULE hModule = LoadLibraryA("combase.dll"); if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) {
if (hModule != NULL) { HSTRING hString;
typedef PCWSTR (WINAPI *WindowsGetStringRawBuffer_t)(HSTRING string, UINT32 *length); hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_get_DisplayName(controller2, &hString);
if (SUCCEEDED(hr)) {
WindowsGetStringRawBuffer_t WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)GetProcAddress(hModule, "WindowsGetStringRawBuffer");
if (WindowsGetStringRawBufferFunc) {
PCWSTR string = WindowsGetStringRawBufferFunc(hString, NULL); PCWSTR string = WindowsGetStringRawBufferFunc(hString, NULL);
if (string) { if (string) {
name = WIN_StringToUTF8(string); name = WIN_StringToUTF8(string);
} }
WindowsDeleteStringFunc(hString);
} }
FreeLibrary(hModule);
} }
FreeLibrary(hModule);
} }
__x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2); __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2);
} }