Exception thrown at ... Access violating reading location

1

Solved: stupid redeclaration issue I failed to notice on my side.

Full exception message below:
Exception thrown at 0x00007FF73EB618D7 in metadata_modifier.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF. occurred
The line in question: SafeRelease(&pIByteStream);


I am trying to create an application in C++ which uses the win32 API to grab a media file's metadata (properties of the file including "Name", "#", "Title", "Contributing artists", etc)

The page at: https://docs.microsoft.com/en-us/windows/win32/medfound/shell-metadata-providers lists 3 steps to achieve this:

  1. Get a pointer to the IMFMediaSource interface of the media source. You can use the IMFSourceResolver interface to get an IMFMediaSource pointer.
  2. Call MFGetService on the media source to get a pointer to the IPropertyStore interface. In the guidService parameter of MFGetService, specify the value MF_PROPERTY_HANDLER_SERVICE. If the source does not support the IPropertyStore interface, MFGetService returns MF_E_UNSUPPORTED_SERVICE.
  3. Call IPropertyStore methods to enumerate the metadata properties.

As it provides a code example for step 2 and 3 (EnumerateMetadata), my code (full code can be found at the bottom) is focused on trying to achieve step 1.

This is an outline of what I am currently doing:

template <class T> void SafeRelease(T **ppT) {
    if (*ppT) {
        (*ppT)->Release();
        *ppT = NULL;
    };
};

...

IMFSourceResolver *pISourceResolver;
IMFByteStream *pIByteStream;

...

HRESULT hr2 = MFCreateSourceResolver(&pISourceResolver);

...

HRESULT hr3 = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, FileName, &pIByteStream);

...

SafeRelease(&pISourceResolver);
SafeRelease(&pIByteStream);

The accepted answer to Exception thrown at 0x00007FF93E507A7A (ntdll.dll) .Access violation reading location 0xFFFFFFFFFFFFFFFF, cannot be the case here as upon looking at the full code, you will see that there is a repeated use of if (SUCCEEDED(hr)) {...}, guaranteeing the success of the previous HRESULT before proceeding to set the value of pIByteStream.

With that said, I understand why this exception is raised and the accepted answer to this https://social.msdn.microsoft.com/Forums/vstudio/en-US/1f850f9e-41fd-4178-9da5-a0f568051309/unhandled-exception-at-access-violation-reading-location-?forum=vclanguage leads me to think I am doing something wrong, but I am not sure what exactly.

Both IMFByteStream and IMFSourceResolver inherit from IUnknown, so both definitely have the Release() method. In addition, both https://docs.microsoft.com/en-us/windows/win32/api/mfapi/nf-mfapi-mfcreatefile and https://docs.microsoft.com/en-us/windows/win32/api/mfidl/nf-mfidl-mfcreatesourceresolver mention that "The caller must release the interface" for the respective out parameter, but SafeRelease(&pISourceResolver); does not throw any exception.

I have attempted to debug the code using VS but, along with Source_MF_OBJECT_TYPE, 2 Locals are generated for pIByteStream - 0x... and 0xcccccccccccccccc. The one with a legit-looking address has <Information not available, no symbols loaded for mfplat.dll> after the address, which leads me to believe it's the "good" pointer, because pISourceResolver also has that and it is released properly, but that variable in particular is generated(?) at the hr3 declaration line, and it is gone after the pSource->QueryInterface(...) line and I have no clue why.

I tried to base my code off the example from https://docs.microsoft.com/en-us/windows/win32/medfound/configuring-a-media-source but even though that example is off MSDN, it does not pass 2 arguments to IUnknown::QueryInterface (https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-queryinterface(refiid_void)) and I couldn't find documentation for IID_PPV_ARGS but I found my code behaved similarly whether I included the macro or not.

*I understand this is probably the umpteenth "Exception thrown at ... Access violation reading location ..." question posted on Stack Overflow and the answer is probably staring me right in the face, but I've been trying to get my head over this for atleast a day now, and I still haven't gotten anything so I would appreciate if someone pointed me in the right direction. Thanks.

Full code:

#include <iostream>
#include <Windows.h>
#include <mfidl.h>
#include <mfobjects.h>
#include <mfapi.h>
#include <Unknwn.h>
#include <wtypes.h>
#include <propsys.h> // IPropertyStore
// Mf.lib
// Mfplat.lib

template <class T> void SafeRelease(T **ppT) {
    if (*ppT)
    {
        (*ppT)->Release();
        *ppT = NULL;
    }
}

HRESULT EnumerateMetadata(IMFMediaSource *pSource) {
    IPropertyStore *pProps = NULL;

    HRESULT hr = MFGetService(
        pSource, MF_PROPERTY_HANDLER_SERVICE, IID_PPV_ARGS(&pProps));

    if (SUCCEEDED(hr)) {
        DWORD cProps;
        hr = pProps->GetCount(&cProps);

        if (SUCCEEDED(hr)) {
            for (DWORD i = 0; i < cProps; i++) {
                PROPERTYKEY key;
                hr = pProps->GetAt(i, &key);

                if (SUCCEEDED(hr)) {
                    PROPVARIANT pv;
                    hr = pProps->GetValue(key, &pv);

                    if (SUCCEEDED(hr)) {
                        //DisplayProperty(key, pv);
                        PropVariantClear(&pv);
                    };
                };
            };
        };
    };

    SafeRelease(&pProps);
    return hr;
};

void CreateMediaSource(IMFMediaSource **ppIMediaSource) {
    PCWSTR FileName = L"C:\\Users\\dlp\\1.mp3";

    IUnknown *pSource;
    IMFSourceResolver *pISourceResolver;
    IMFByteStream *pIByteStream;
    MF_OBJECT_TYPE Source_MF_OBJECT_TYPE;

    HRESULT hr0 = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    HRESULT hr1 = MFStartup(MF_VERSION);

    HRESULT hr2 = MFCreateSourceResolver(&pISourceResolver);

    if (SUCCEEDED(hr2)) {    
        IMFByteStream* pIByteStream;
        MF_OBJECT_TYPE Source_MF_OBJECT_TYPE;

        HRESULT hr3 = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, FileName, &pIByteStream);

        if (SUCCEEDED(hr3)) {
            HRESULT hr4 = pISourceResolver->CreateObjectFromByteStream(pIByteStream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL, &Source_MF_OBJECT_TYPE, &pSource);

            if (SUCCEEDED(hr4)) {
                pSource->QueryInterface(ppIMediaSource);
            };
        };
    };
    SafeRelease(&pISourceResolver);
    SafeRelease(&pIByteStream);
}

int main() {
    IMFMediaSource *IMediaSource = NULL;
    CreateMediaSource(&IMediaSource);
    EnumerateMetadata(IMediaSource);

    return 0;
};```
c++
windows
asked on Stack Overflow Aug 15, 2020 by dlp • edited Aug 15, 2020 by dlp

1 Answer

2
void CreateMediaSource(IMFMediaSource **ppIMediaSource) {
    ....
    
    IMFByteStream *pIByteStream; // HERE
   
    ....
    
    if (SUCCEEDED(hr2)) {    
        IMFByteStream* pIByteStream; // HERE

        HRESULT hr3 = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, FileName, &pIByteStream);

        ....
   }   
   SafeRelease(&pIByteStream);
}

The one you release isn't even initialized. Remove the second declaration.

answered on Stack Overflow Aug 15, 2020 by s d • edited Aug 15, 2020 by s d

User contributions licensed under CC BY-SA 3.0