Why is QueryInterface() returning E_INVALIDARG?

223 Views Asked by At

I was coding a project and I came across a bug where QueryInterface() was returning E_INVALIDARG, I don't know which argument is invalid because both arguments are simple enough, am I overlooking something simple or what?

The bit that that is failing comes from Microsoft themselves specifically documentation, if I'm doing something totally wrong tell me

HRESULT CreateSecondaryBuffer(LPDIRECTSOUND8 lpDirectSound, LPDIRECTSOUNDBUFFER8* ppDsb8, LPCWSTR lpName) {
    WAVEFORMATEX wfx;
    DSBUFFERDESC dsbdesc;
    LPDIRECTSOUNDBUFFER pDsb = NULL;
    HRESULT hr = 0;

    void* lpRes;
    HRSRC hResInfo;
    HGLOBAL hRes;

    LPVOID lpvWrite;
    DWORD  dwLength;

    waveFile myWave;
    memset(&myWave, 0, sizeof(waveFile));
    // Find the WAVE resource. 

    hResInfo = FindResource(wc.hInstance, lpName, L"WAVE");
    if (hResInfo == NULL)
        return FALSE;

    // Load the WAVE resource. 

    hRes = LoadResource(wc.hInstance, hResInfo);
    if (hRes == NULL)
        return FALSE;

    // Lock the WAVE resource and play it. 

    lpRes = LockResource(hRes);
    char* wavMem = static_cast<char*>(lpRes);
    memcpy(&myWave, wavMem, 36);
    wavMem += 36;
    

    while (myWave.Subchunk2ID[0] != 'd' && myWave.Subchunk2ID[1] != 'a' && myWave.Subchunk2ID[2] != 't' && myWave.Subchunk2ID[3] != 'a') {
        memcpy(&myWave.Subchunk2ID, wavMem, 8);
        if (myWave.Subchunk2ID[0] != 'd' && myWave.Subchunk2ID[1] != 'a' && myWave.Subchunk2ID[2] != 't' && myWave.Subchunk2ID[3] != 'a') {
            wavMem += myWave.Subchunk2Size;
            wavMem += 8;
        }
    }
    wavMem += 8;

    char* soundData = new char[myWave.Subchunk2Size];
    memcpy(soundData, wavMem, myWave.Subchunk2Size);
    FreeResource(hRes);

    // Set up WAV format structure. 

    memset(&wfx, 0, sizeof(WAVEFORMATEX));
    wfx.wFormatTag = WAVE_FORMAT_PCM;
    wfx.nChannels = myWave.NumChannels;
    wfx.nSamplesPerSec = myWave.SampleRate;
    wfx.nBlockAlign = myWave.BlockAlign;
    wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
    wfx.wBitsPerSample = myWave.BitsPerSample;

    // Set up DSBUFFERDESC structure. 

    memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
    dsbdesc.dwSize = sizeof(DSBUFFERDESC);
    dsbdesc.dwFlags =
         DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS;
    dsbdesc.dwBufferBytes = myWave.Subchunk2Size;
    dsbdesc.lpwfxFormat = &wfx;

    hr = lpDirectSound->CreateSoundBuffer(&dsbdesc, &pDsb, NULL);
    if (SUCCEEDED(hr))
    {
        if (DS_OK == pDsb->Lock(
            0,          // Offset at which to start lock.
            0,          // Size of lock; ignored because of flag.
            &lpvWrite,  // Gets address of first part of lock.
            &dwLength,  // Gets size of first part of lock.
            NULL,       // Address of wraparound not needed. 
            NULL,       // Size of wraparound not needed.
            DSBLOCK_ENTIREBUFFER))  // Flag.
        {
            memcpy(lpvWrite, soundData, dwLength);
            pDsb->Unlock(
                lpvWrite,   // Address of lock start.
                dwLength,   // Size of lock.
                NULL,       // No wraparound portion.
                0);         // No wraparound size.
        }
        hr = pDsb->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)ppDsb8);
        pDsb->Release();
    }

    delete[] soundData;
    return hr;
}
1

There are 1 best solutions below

2
On BEST ANSWER

There are only 2 parameters to QueryInterface() for E_INVALIDARG to complain about, and offhand they look fine to me inside of your CreateSecondaryBuffer() function. The 1st parameter is being passed a hard-coded IID, so the problem has to be with the 2nd parameter, which expects to be passed a pointer to (in this case) an IDirectSoundBuffer8* variable that QueryInterface() can write the memory address of a DirectSoundBuffer8 object into. So most likely, the ppDsb8 parameter of your CreateSecondaryBuffer() function is not being passed a valid pointer to a IDirectSoundBuffer8* variable, like you are expecting.

UPDATE: After seeing your added comment, you are indeed passing an invalid pointer to the ppDsb8 parameter of CreateSecondaryBuffer(). The caller's pMainSecondaryBuffer pointer is being declared incorrectly, and is uninitialized when passed to CreateSecondaryBuffer(), so you are passing a bad pointer to QueryInterface(), hence the E_INVALIDARG error.

Use this instead:

LPDIRECTSOUND8 lpDevice = ...; // <-- make sure it points to a valid device object...
LPDIRECTSOUNDBUFFER8 pMainSecondaryBuffer;
CreateSecondaryBuffer(lpDevice, &pMainSecondaryBuffer, L"mainSong");