Example #1
0
HRESULT STDMETHODCALLTYPE Blt(LPDIRECTDRAWSURFACE7 surface, LPRECT lpDestRect, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
{
    //logOutput << CurrentTimeString() << "Hooked Blt()" << endl;

    EnterCriticalSection(&ddrawMutex);

    ddrawSurfaceBlt.Unhook();
    HRESULT hr = surface->Blt(lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
    ddrawSurfaceBlt.Rehook();

    if (SUCCEEDED(hr))
    {
        if (!g_bUseFlipMethod)
        {
            if (getFrontSurface(surface))
            {
                CaptureDDraw();
            }
        }
    }

    LeaveCriticalSection(&ddrawMutex);

    return hr;
}
Example #2
0
HRESULT STDMETHODCALLTYPE CreateSurface(IDirectDraw7* ddInterface, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPDIRECTDRAWSURFACE7 *lplpDDSurface, IUnknown *pUnkOuter)
{
    //logOutput << CurrentTimeString() << "Hooked CreateSurface()" << endl;

    if (!g_ddInterface)
    {
        if (ddInterface->QueryInterface(IID_IDirectDraw, (LPVOID*)&g_ddInterface) == S_OK)
        {
            logOutput << CurrentTimeString() << "IDirectDraw::CreateSurface: got DDInterface pointer" << endl;
        }
        else
        {
            logOutput << CurrentTimeString() << "IDirectDraw::CreateSurface: could not query DirectDraw interface" << endl;
        }
    }

    ddrawSurfaceCreate.Unhook();
    HRESULT hRes = ddInterface->CreateSurface(lpDDSurfaceDesc, lplpDDSurface, pUnkOuter);
    ddrawSurfaceCreate.Rehook();

    if (hRes == DD_OK)
    {
        if (lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
        {
            logOutput << CurrentTimeString() << "IDirectDraw::CreateSurface: Primary surface created at 0x" << *lplpDDSurface << endl;
            getFrontSurface(*lplpDDSurface);
        }
    }
    else
        printDDrawError(hRes, "CreateSurface");

    return hRes;
}
Example #3
0
void CheckDDrawCapture()
{
    EnterCriticalSection(&ddrawMutex);
    ddrawSurfaceUnlock.Rehook(true);
    ddrawSurfaceFlip.Rehook(true);
    ddrawSurfaceBlt.Rehook(true);
    LeaveCriticalSection(&ddrawMutex);
}
Example #4
0
void HookAll()
{
    ddrawSurfaceCreate.Rehook();
    ddrawSurfaceRestore.Rehook();
    ddrawSurfaceRelease.Rehook();
    ddrawSurfaceSetPalette.Rehook();
    ddrawPaletteSetEntries.Rehook();
}
Example #5
0
void FreeGLCapture()
{
    glHookSwapBuffers.Unhook();
    glHookSwapLayerBuffers.Unhook();
    glHookwglSwapBuffers.Unhook();
    glHookDeleteContext.Unhook();

    ClearGLData();
}
Example #6
0
BOOL WINAPI wglDeleteContextHook(HGLRC hRC)
{
    HandleGLSceneDestroy();

    glHookDeleteContext.Unhook();
    BOOL bResult = jimglDeleteContext(hRC);
    glHookDeleteContext.Rehook();

    return bResult;
}
Example #7
0
BOOL WINAPI wglSwapLayerBuffersHook(HDC hDC, UINT fuPlanes)
{
    HandleGLSceneUpdate(hDC);

    glHookSwapLayerBuffers.Unhook();
    BOOL bResult = jimglSwapLayerBuffers(hDC, fuPlanes);
    glHookSwapLayerBuffers.Rehook();

    return bResult;
}
Example #8
0
BOOL WINAPI SwapBuffersHook(HDC hDC)
{
    HandleGLSceneUpdate(hDC);

    glHookSwapBuffers.Unhook();
    BOOL bResult = SwapBuffers(hDC);
    glHookSwapBuffers.Rehook(); 

    return bResult;
}
Example #9
0
    void ReloadPrimarySurfacePaletteEntries()
    {
        if (!primary_surface_palette_ref)
            return;

        HRESULT err;
        ddrawPaletteSetEntries.Unhook();
        if (FAILED(err = primary_surface_palette_ref->SetEntries(0, 0, numEntries, entries)))
        {
            logOutput << CurrentTimeString() << "ReloadPrimarySurfacePaletteEntries(): could not set entires" << endl;
            printDDrawError(err);
        }
        ddrawPaletteSetEntries.Rehook();
    }
Example #10
0
bool InitD3D11Capture()
{
    bool bSuccess = false;

    HMODULE hD3D11Dll = GetModuleHandle(TEXT("d3d11.dll"));
    if(hD3D11Dll)
    {
        D3D11CREATEPROC d3d11Create = (D3D11CREATEPROC)GetProcAddress(hD3D11Dll, "D3D11CreateDeviceAndSwapChain");
        if(d3d11Create)
        {
            DXGI_SWAP_CHAIN_DESC swapDesc;
            ZeroMemory(&swapDesc, sizeof(swapDesc));
            swapDesc.BufferCount = 2;
            swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
            swapDesc.BufferDesc.Width  = 2;
            swapDesc.BufferDesc.Height = 2;
            swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
            swapDesc.OutputWindow = hwndSender;
            swapDesc.SampleDesc.Count = 1;
            swapDesc.Windowed = TRUE;

            IDXGISwapChain *swap;
            ID3D11Device *device;
            ID3D11DeviceContext *context;

            D3D_FEATURE_LEVEL desiredLevel = D3D_FEATURE_LEVEL_11_0;
            D3D_FEATURE_LEVEL receivedLevel;

            HRESULT hErr;
            if(SUCCEEDED(hErr = (*d3d11Create)(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &desiredLevel, 1, D3D11_SDK_VERSION, &swapDesc, &swap, &device, &receivedLevel, &context)))
            {
                bSuccess = true;

                UPARAM *vtable = *(UPARAM**)swap;
                gi11swapPresent.Hook((FARPROC)*(vtable+(32/4)), ConvertClassProcToFarproc((CLASSPROC)&D3D11Override::SwapPresentHook));
                gi11swapResizeBuffers.Hook((FARPROC)*(vtable+(52/4)), ConvertClassProcToFarproc((CLASSPROC)&D3D11Override::SwapResizeBuffersHook));

                SafeRelease(swap);
                SafeRelease(device);
                SafeRelease(context);

                gi11swapPresent.Rehook();
                gi11swapResizeBuffers.Rehook();
            }
        }
    }

    return bSuccess;
}
Example #11
0
HRESULT STDMETHODCALLTYPE SetPalette(LPDIRECTDRAWSURFACE7 surface, LPDIRECTDRAWPALETTE lpDDPalette)
{
    //logOutput << CurrentTimeString() << "Hooked SetPalette()" << endl;

    ddrawSurfaceSetPalette.Unhook();
    HRESULT hr = surface->SetPalette(lpDDPalette);
    ddrawSurfaceSetPalette.Rehook();

    if (getFrontSurface(surface))
    {
        if (lpDDPalette)
            lpDDPalette->AddRef();
        SetupPalette(lpDDPalette);
    }

    return hr;
}
Example #12
0
HRESULT STDMETHODCALLTYPE PaletteSetEntries(LPDIRECTDRAWPALETTE palette, DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries)
{
    //logOutput << CurrentTimeString() << "Hooked SetEntries()" << endl;

    ddrawPaletteSetEntries.Unhook();
    HRESULT hr = palette->SetEntries(dwFlags, dwStartingEntry, dwCount, lpEntries);
    ddrawPaletteSetEntries.Rehook();

    // update buffer palette
    if (SUCCEEDED(hr))
    {
        if (g_CurrentPalette.bInitialized)
        {
            memcpy(g_CurrentPalette.entries + dwStartingEntry, lpEntries, 4 * dwCount); // each entry is 4 bytes if DDCAPS_8BITENTRIES flag is not set
        }
    }

    return hr;
}
Example #13
0
inline HRESULT STDMETHODCALLTYPE UnlockSurface(LPDIRECTDRAWSURFACE7 surface, LPRECT data)
{
    //logOutput << CurrentTimeString() << "Called UnlockSurface" << endl;

    // standard handler
    if (!bTargetAcquired)
    {
        ddrawSurfaceUnlock.Unhook();
        HRESULT hr = surface->Unlock(data);
        ddrawSurfaceUnlock.Rehook();
        return hr;
    }

    // use mutex lock to prevent memory corruption when calling Unhook/Rehook from multiple threads
    HANDLE mutex = OpenMutex(SYNCHRONIZE, FALSE, mutexName);
    if (!mutex)
    {
        logOutput << CurrentTimeString() << "Could not open mutex - Error(" << GetLastError() << ')' << endl;
        return DDERR_GENERIC;
    }

    DWORD ret = WaitForSingleObject(mutex, INFINITE);
    if (ret == WAIT_OBJECT_0)
    {
        ddrawSurfaceUnlock.Unhook();
        HRESULT hr = surface->Unlock(data);
        ddrawSurfaceUnlock.Rehook();

        ReleaseMutex(mutex);
        CloseHandle(mutex);
        return hr;
    }
    else
    {
        logOutput << CurrentTimeString() << "error while waiting for unlock-mutex to get signaled" << endl;
        logOutput << CurrentTimeString() << "GetLastError: " << GetLastError() << endl;
        CloseHandle(mutex);
        return DDERR_GENERIC;
    }
}
Example #14
0
HRESULT STDMETHODCALLTYPE D3D11SwapResizeBuffersHook(IDXGISwapChain *swap, UINT bufferCount, UINT width, UINT height, DXGI_FORMAT giFormat, UINT flags)
{
    ClearD3D11Data();
    lpCurrentSwap = NULL;
    lpCurrentDevice = NULL;
    bTargetAcquired = false;

    gi11swapResizeBuffers.Unhook();
    HRESULT hRes = swap->ResizeBuffers(bufferCount, width, height, giFormat, flags);
    gi11swapResizeBuffers.Rehook();

    /*if(lpCurrentSwap == NULL && !bTargetAcquired)
    {
        lpCurrentSwap = swap;
        bTargetAcquired = true;
    }

    if(lpCurrentSwap == swap)
        SetupD3D11(swap);*/

    return hRes;
}
Example #15
0
HRESULT STDMETHODCALLTYPE Restore(LPDIRECTDRAWSURFACE7 surface)
{
    //logOutput << CurrentTimeString() << "Hooked Restore()" << endl;

    ddrawSurfaceRestore.Unhook();
    HRESULT hr = surface->Restore();

    if (bHasTextures)
    {
        if (surface == g_frontSurface)
        {
            logOutput << CurrentTimeString() << "SurfaceRestore: restoring offscreen buffers" << endl;
            bool success = true;
            for (UINT i = 0; i < NUM_BUFFERS; i++)
            {
                HRESULT err;
                if (FAILED(err = ddCaptures[i]->Restore()))
                {
                    logOutput << CurrentTimeString() << "SurfaceRestore: error restoring offscreen buffer" << endl;
                    printDDrawError(err, "Restore");
                    success = false;
                }
            }
            if (!success)
            {
                CleanUpDDraw();
            }
        }
    }
    ddrawSurfaceRestore.Rehook();

    if (!bHasTextures)
    {
        getFrontSurface(surface);
    }

    return hr;
}
Example #16
0
HRESULT STDMETHODCALLTYPE Flip(LPDIRECTDRAWSURFACE7 surface, LPDIRECTDRAWSURFACE7 lpDDSurface, DWORD flags)
{
    //logOutput << CurrentTimeString() << "Hooked Flip()" << endl;

    HRESULT hr;

    EnterCriticalSection(&ddrawMutex);

    ddrawSurfaceFlip.Unhook();
    hr = surface->Flip(lpDDSurface, flags);
    ddrawSurfaceFlip.Rehook();

    g_bUseFlipMethod = true;

    if (getFrontSurface(surface))
    {
        CaptureDDraw();
    }

    LeaveCriticalSection(&ddrawMutex);

    return hr;
}
Example #17
0
ULONG STDMETHODCALLTYPE Release(LPDIRECTDRAWSURFACE7 surface)
{
    //logOutput << CurrentTimeString() << "Hooked Release()" << endl;

    ddrawSurfaceRelease.Unhook();
    /*
    if(surface == g_frontSurface)
    {
    logOutput << CurrentTimeString() << "Releasing primary surface 0x" << surface << endl;
    surface->AddRef();
    ULONG refCount = surface->Release();

    if(refCount == 1)
    {
    logOutput << CurrentTimeString() << "Freeing primary surface" << endl;
    g_frontSurface = NULL;
    bTargetAcquired = false;
    CleanUpDDraw();
    }
    }
    */

    ULONG refCount = surface->Release();
    ddrawSurfaceRelease.Rehook();

    if (surface == g_frontSurface)
    {
        if (refCount == 0)
        {
            logOutput << CurrentTimeString() << "Freeing primary surface" << endl;
            CleanUpDDraw();
        }
    }

    return refCount;
}
Example #18
0
bool SetupDDraw()
{
    logOutput << CurrentTimeString() << "called SetupDDraw()" << endl;

    if (!g_ddInterface)
    {
        logOutput << CurrentTimeString() << "SetupDDraw: DirectDraw interface not set, returning" << endl;
        return false;
    }

    bool bSuccess = true;

    bKillThread = false;

    if (hCopyThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CopyDDrawTextureThread, NULL, 0, NULL))
    {
        if (!(hCopyEvent = CreateEvent(NULL, FALSE, FALSE, NULL)))
        {
            logOutput << CurrentTimeString() << "SetupDDraw: CreateEvent failed, GetLastError = " << GetLastError() << endl;
            bSuccess = false;
        }
    }
    else
    {
        logOutput << CurrentTimeString() << "SetupDDraw: CreateThread failed, GetLastError = " << GetLastError() << endl;
        bSuccess = false;
    }

    if (bSuccess)
    {
        if (!ddUnlockFctMutex)
        {
            ddUnlockFctMutex = CreateMutex(NULL, FALSE, mutexName);
            if (!ddUnlockFctMutex)
            {
                RUNEVERYRESET logOutput << CurrentTimeString() << "SetupDDraw: CreateMutex failed, GetLastError = " << GetLastError() << endl;
                bSuccess = false;
            }
        }
    }

    if (bSuccess && !g_frontSurface)
    {
        RUNEVERYRESET logOutput << "SetupDDraw: frontSurface and surface descriptor not set, returning" << endl;
        CleanUpDDraw();
        return false;
    }
    else if (bSuccess)
    {
        LPDIRECTDRAWPALETTE palette = NULL;
        HRESULT err;
        if (SUCCEEDED(err = g_frontSurface->GetPalette(&palette)))
        {
            if (palette)
                SetupPalette(palette);
        }
        else if (err == DDERR_NOPALETTEATTACHED)
        {
            //logOutput << CurrentTimeString() << "No palette attached to primary surface" << endl;
        }
        else
        {
            logOutput << CurrentTimeString() << "Error retrieving palette" << endl;
            printDDrawError(err, "getFrontSurface");
        }
    }

    if (bSuccess && !g_surfaceDesc)
    {
        logOutput << CurrentTimeString() << "SetupDDraw: no surface descriptor found, creating a new one (not an error)" << endl;

        g_surfaceDesc = new DDSURFACEDESC2;
        g_surfaceDesc->dwSize = sizeof(DDSURFACEDESC);

        HRESULT hr;
        if (FAILED(hr = ((LPDIRECTDRAWSURFACE)g_frontSurface)->GetSurfaceDesc((LPDDSURFACEDESC)g_surfaceDesc)))
        {
            g_surfaceDesc->dwSize = sizeof(DDSURFACEDESC2);
            if (FAILED(g_frontSurface->GetSurfaceDesc(g_surfaceDesc)))
            {
                logOutput << CurrentTimeString() << "SetupDDraw: error getting surface descriptor" << endl;
                printDDrawError(hr, "SetupDDraw");
                bSuccess = false;
            }
        }
    }

    if (bSuccess && g_surfaceDesc)
    {
        const DDPIXELFORMAT& pf = g_surfaceDesc->ddpfPixelFormat;
        if (pf.dwFlags & DDPF_RGB)
        {
            if (pf.dwRGBBitCount == 16)
            {
                logOutput << CurrentTimeString() << "SetupDDraw: found 16bit format (using R5G6B5 conversion)" << endl;
                g_bConvert16to32 = true;
            }
            else if (pf.dwRGBBitCount == 32)
            {
                logOutput << CurrentTimeString() << "SetupDDraw: found 32bit format (using plain copy)" << endl;
                g_bUse32bitCapture = true;
            }
        }
        else if (pf.dwFlags & (DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED2 | DDPF_PALETTEINDEXED1))
        {
            logOutput << CurrentTimeString() << "SetupDDraw: front surface uses palette indices" << endl;
        }
    }

    if (bSuccess)
    {
        logOutput << CurrentTimeString() << "SetupDDraw: primary surface width = " << g_surfaceDesc->dwWidth << ", height = " << g_surfaceDesc->dwHeight << endl;
        g_dwSize = g_surfaceDesc->lPitch*g_surfaceDesc->dwHeight;
        ddrawCaptureInfo.captureType = CAPTURETYPE_MEMORY;
        ddrawCaptureInfo.cx = g_surfaceDesc->dwWidth;
        ddrawCaptureInfo.cy = g_surfaceDesc->dwHeight;
        ddrawCaptureInfo.pitch = 4 * ddrawCaptureInfo.cx;
        ddrawCaptureInfo.hwndCapture = (DWORD)hwndSender;
        ddrawCaptureInfo.format = GS_BGRA;
        DWORD g_dwCaptureSize = ddrawCaptureInfo.pitch*ddrawCaptureInfo.cy;
        ddrawCaptureInfo.bFlip = FALSE;
        ddrawCaptureInfo.mapID = InitializeSharedMemoryCPUCapture(g_dwCaptureSize, &ddrawCaptureInfo.mapSize, &copyData, textureBuffers);

        memcpy(infoMem, &ddrawCaptureInfo, sizeof(CaptureInfo));

        DDSURFACEDESC2 captureDesc;
        ZeroMemory(&captureDesc, sizeof(captureDesc));
        captureDesc.dwSize = sizeof(DDSURFACEDESC2);

        captureDesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_PITCH;
        captureDesc.dwWidth = g_surfaceDesc->dwWidth;
        captureDesc.dwHeight = g_surfaceDesc->dwHeight;
        captureDesc.lPitch = g_surfaceDesc->lPitch;
        captureDesc.ddpfPixelFormat = g_surfaceDesc->ddpfPixelFormat;
        captureDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;

        HRESULT err;

        ddrawSurfaceCreate.Unhook();
        for (int i = 0; i < NUM_BUFFERS && bSuccess; i++)
        {
            if (FAILED(err = g_ddInterface->CreateSurface(&captureDesc, &ddCaptures[i], NULL)))
            {
                logOutput << CurrentTimeString() << "SetupDDraw: Could not create offscreen capture" << endl;
                printDDrawError(err, "SetupDDraw");
                bSuccess = false;
                break;
            }
        }
        ddrawSurfaceCreate.Rehook();

        if (bSuccess)
        {
            bHasTextures = true;

            SetEvent(hSignalReady);

            OSInitializeTimer();
        }
    }

    if (bSuccess)
    {
        logOutput << CurrentTimeString() << "SetupDDraw successfull" << endl;
        HookAll();
        return true;
    }
    else
    {
        logOutput << CurrentTimeString() << "SetupDDraw failed" << endl;
        CleanUpDDraw();
        return false;
    }
}
Example #19
0
void FreeD3D11Capture()
{
    gi11swapPresent.Unhook();
    gi11swapResizeBuffers.Unhook();
}
Example #20
0
    HRESULT STDMETHODCALLTYPE SwapPresentHook(UINT syncInterval, UINT flags)
    {
        IDXGISwapChain *swap = (IDXGISwapChain*)this;

        if(lpCurrentSwap == NULL && !bTargetAcquired)
        {
            lpCurrentSwap = swap;
            SetupD3D11(swap);
            bTargetAcquired = true;
        }

        if(lpCurrentSwap == swap)
        {
            ID3D11Device *device = NULL;
            HRESULT chi;
            if(SUCCEEDED(chi = swap->GetDevice(__uuidof(ID3D11Device), (void**)&device)))
            {
                if(!lpCurrentDevice)
                {
                    lpCurrentDevice = device;

                    oldD3D11Release = GetVTable(device, (8/4));
                    newD3D11Release = ConvertClassProcToFarproc((CLASSPROC)&D3D11Override::DeviceReleaseHook);
                    SetVTable(device, (8/4), newD3D11Release);
                }

                ID3D11DeviceContext *context;
                device->GetImmediateContext(&context);

                if(!bHasTextures && bCapturing)
                {
                    if(dxgiFormat)
                    {
                        if(!hwndReceiver)
                            hwndReceiver = FindWindow(RECEIVER_WINDOWCLASS, NULL);

                        if(hwndReceiver)
                        {
                            D3D11_TEXTURE2D_DESC texDesc;
                            ZeroMemory(&texDesc, sizeof(texDesc));
                            texDesc.Width  = d3d11CaptureInfo.cx;
                            texDesc.Height = d3d11CaptureInfo.cy;
                            texDesc.MipLevels = 1;
                            texDesc.ArraySize = 1;
                            texDesc.Format = dxgiFormat;
                            texDesc.SampleDesc.Count = 1;
                            texDesc.Usage = D3D11_USAGE_STAGING;
                            texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;

                            bool bSuccess = true;
                            UINT pitch;

                            for(UINT i=0; i<2; i++)
                            {
                                HRESULT ching;
                                if(FAILED(ching = device->CreateTexture2D(&texDesc, NULL, &d3d11Textures[i])))
                                {
                                    bSuccess = false;
                                    break;
                                }

                                if(i == 0)
                                {
                                    ID3D11Resource *resource;
                                    if(FAILED(d3d11Textures[i]->QueryInterface(__uuidof(ID3D11Resource), (void**)&resource)))
                                    {
                                        bSuccess = false;
                                        break;
                                    }

                                    D3D11_MAPPED_SUBRESOURCE map;
                                    if(FAILED(context->Map(resource, 0, D3D11_MAP_READ, 0, &map)))
                                    {
                                        bSuccess = false;
                                        break;
                                    }

                                    pitch = map.RowPitch;
                                    context->Unmap(resource, 0);
                                    resource->Release();
                                }
                            }

                            if(bSuccess)
                            {
                                d3d11CaptureInfo.mapID = InitializeSharedMemory(pitch*d3d11CaptureInfo.cy, &d3d11CaptureInfo.mapSize, &copyData, textureBuffers);
                                if(!d3d11CaptureInfo.mapID)
                                    bSuccess = false;
                            }

                            if(bSuccess)
                            {
                                bHasTextures = true;
                                d3d11CaptureInfo.captureType = CAPTURETYPE_MEMORY;
                                d3d11CaptureInfo.hwndSender = hwndSender;
                                d3d11CaptureInfo.pitch = pitch;
                                d3d11CaptureInfo.bFlip = FALSE;
                                PostMessage(hwndReceiver, RECEIVER_NEWCAPTURE, 0, (LPARAM)&d3d11CaptureInfo);
                            }
                            else
                            {
                                for(UINT i=0; i<2; i++)
                                {
                                    SafeRelease(d3d11Textures[i]);

                                    if(textureBuffers[i])
                                    {
                                        free(textureBuffers[i]);
                                        textureBuffers[i] = NULL;
                                    }
                                }
                            }
                        }
                    }
                }

                if(bHasTextures)
                {
                    if(bCapturing)
                    {
                        DWORD nextCapture = curCapture == 0 ? 1 : 0;

                        ID3D11Texture2D *texture = d3d11Textures[curCapture];
                        ID3D11Resource *backBuffer = NULL;

                        if(SUCCEEDED(swap->GetBuffer(0, IID_ID3D11Resource, (void**)&backBuffer)))
                        {
                            if(bIsMultisampled)
                                context->ResolveSubresource(texture, 0, backBuffer, 0, dxgiFormat);
                            else
                                context->CopyResource(texture, backBuffer);
                            backBuffer->Release();

                            ID3D11Texture2D *lastTexture = d3d11Textures[nextCapture];
                            ID3D11Resource *resource;

                            if(SUCCEEDED(lastTexture->QueryInterface(__uuidof(ID3D11Resource), (void**)&resource)))
                            {
                                D3D11_MAPPED_SUBRESOURCE map;
                                if(SUCCEEDED(context->Map(resource, 0, D3D11_MAP_READ, 0, &map)))
                                {
                                    LPBYTE *pTextureBuffer = NULL;
                                    int lastRendered = -1;

                                    //under no circumstances do we -ever- allow a stall
                                    if(WaitForSingleObject(textureMutexes[curCapture], 0) == WAIT_OBJECT_0)
                                        lastRendered = (int)curCapture;
                                    else if(WaitForSingleObject(textureMutexes[nextCapture], 0) == WAIT_OBJECT_0)
                                        lastRendered = (int)nextCapture;

                                    if(lastRendered != -1)
                                    {
                                        SSECopy(textureBuffers[lastRendered], map.pData, map.RowPitch*d3d11CaptureInfo.cy);
                                        ReleaseMutex(textureMutexes[lastRendered]);
                                    }

                                    context->Unmap(resource, 0);
                                    copyData->lastRendered = (UINT)lastRendered;
                                }

                                resource->Release();
                            }
                        }

                        curCapture = nextCapture;
                    }
                    else
                        ClearD3D11Data();
                }

                device->Release();
                context->Release();
            }
        }

        gi11swapPresent.Unhook();
        HRESULT hRes = swap->Present(syncInterval, flags);
        gi11swapPresent.Rehook();

        return hRes;
    }
Example #21
0
bool InitD3D11Capture()
{
    bool bSuccess = false;

    HMODULE hD3D11Dll = GetModuleHandle(TEXT("d3d11.dll"));
    if(hD3D11Dll)
    {
        D3D11CREATEPROC d3d11Create = (D3D11CREATEPROC)GetProcAddress(hD3D11Dll, "D3D11CreateDeviceAndSwapChain");
        if(d3d11Create)
        {
            DXGI_SWAP_CHAIN_DESC swapDesc;
            ZeroMemory(&swapDesc, sizeof(swapDesc));
            swapDesc.BufferCount = 2;
            swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
            swapDesc.BufferDesc.Width  = 2;
            swapDesc.BufferDesc.Height = 2;
            swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
            swapDesc.OutputWindow = hwndSender;
            swapDesc.SampleDesc.Count = 1;
            swapDesc.Windowed = TRUE;

            IDXGISwapChain *swap;
            ID3D11Device *device;
            ID3D11DeviceContext *context;

            D3D_FEATURE_LEVEL desiredLevels[6] =
            {
                D3D_FEATURE_LEVEL_11_0,
                D3D_FEATURE_LEVEL_10_1,
                D3D_FEATURE_LEVEL_10_0,
                D3D_FEATURE_LEVEL_9_3,
                D3D_FEATURE_LEVEL_9_2,
                D3D_FEATURE_LEVEL_9_1,
            };
            D3D_FEATURE_LEVEL receivedLevel;

            HRESULT hErr;
            if(SUCCEEDED(hErr = (*d3d11Create)(NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, desiredLevels, 6, D3D11_SDK_VERSION, &swapDesc, &swap, &device, &receivedLevel, &context)))
            {
                bSuccess = true;

                UPARAM *vtable = *(UPARAM**)swap;
                gi11swapPresent.Hook((FARPROC)*(vtable+(32/4)), (FARPROC)D3D11SwapPresentHook);
                gi11swapResizeBuffers.Hook((FARPROC)*(vtable+(52/4)), (FARPROC)D3D11SwapResizeBuffersHook);

                SafeRelease(swap);
                SafeRelease(device);
                SafeRelease(context);

                gi11swapPresent.Rehook();
                gi11swapResizeBuffers.Rehook();
            }
            else
            {
                RUNONCE logOutput << "InitD3D11Capture: D3D11CreateDeviceAndSwapChain definitely failed, result = " << UINT(hErr) << endl;
            }
        }
        else
        {
            RUNONCE logOutput << "InitD3D11Capture: could not get address of D3D11CreateDeviceAndSwapChain" << endl;
        }
    }

    return bSuccess;
}
Example #22
0
HRESULT STDMETHODCALLTYPE D3D11SwapPresentHook(IDXGISwapChain *swap, UINT syncInterval, UINT flags)
{
    if(lpCurrentSwap == NULL && !bTargetAcquired)
    {
        lpCurrentSwap = swap;
        SetupD3D11(swap);
        bTargetAcquired = true;
    }

    if(lpCurrentSwap == swap)
    {
        ID3D11Device *device = NULL;
        HRESULT chi;
        if(SUCCEEDED(chi = swap->GetDevice(__uuidof(ID3D11Device), (void**)&device)))
        {
            if(!lpCurrentDevice)
            {
                lpCurrentDevice = device;

                /*FARPROC curRelease = GetVTable(device, (8/4));
                if(curRelease != newD3D11Release)
                {
                    oldD3D11Release = curRelease;
                    newD3D11Release = (FARPROC)DeviceReleaseHook;
                    SetVTable(device, (8/4), newD3D11Release);
                }*/
            }

            ID3D11DeviceContext *context;
            device->GetImmediateContext(&context);

            if(bCapturing && bStopRequested)
            {
                ClearD3D11Data();
                bStopRequested = false;
            }

            if(!bHasTextures && bCapturing)
            {
                if(dxgiFormat)
                {
                    if(!hwndReceiver)
                        hwndReceiver = FindWindow(RECEIVER_WINDOWCLASS, NULL);

                    if(hwndReceiver)
                    {
                        BOOL bSuccess = DoD3D11Hook(device);

                        if(bSuccess)
                        {
                            d3d11CaptureInfo.mapID = InitializeSharedMemoryGPUCapture(&texData);
                            if(!d3d11CaptureInfo.mapID)
                            {
                                RUNONCE logOutput << "SwapPresentHook: creation of shared memory failed" << endl;
                                bSuccess = false;
                            }
                        }

                        if(bSuccess)
                            bSuccess = IsWindow(hwndReceiver);

                        if(bSuccess)
                        {
                            bHasTextures = true;
                            d3d11CaptureInfo.captureType = CAPTURETYPE_SHAREDTEX;
                            d3d11CaptureInfo.hwndSender = hwndSender;
                            d3d11CaptureInfo.bFlip = FALSE;
                            texData->texHandles[0] = sharedHandles[0];
                            texData->texHandles[1] = sharedHandles[1];
                            PostMessage(hwndReceiver, RECEIVER_NEWCAPTURE, 0, (LPARAM)&d3d11CaptureInfo);

                            logOutput << "DoD3D11Hook: success";
                        }
                        else
                        {
                            ClearD3D11Data();
                        }
                    }
                }
            }

            if(bHasTextures)
            {
                LONGLONG frameTime;
                if(bCapturing)
                {
                    if(texData)
                    {
                        if(frameTime = texData->frameTime)
                        {
                            LONGLONG timeVal = OSGetTimeMicroseconds();
                            LONGLONG timeElapsed = timeVal-lastTime;

                            if(timeElapsed >= frameTime)
                            {
                                lastTime += frameTime;
                                if(timeElapsed > frameTime*2)
                                    lastTime = timeVal;

                                DWORD nextCapture = curCapture == 0 ? 1 : 0;

                                ID3D11Resource *backBuffer = NULL;

                                if(SUCCEEDED(swap->GetBuffer(0, IID_ID3D11Resource, (void**)&backBuffer)))
                                {
                                    if(bIsMultisampled)
                                        context->ResolveSubresource(copyTextureGame, 0, backBuffer, 0, dxgiFormat);
                                    else
                                        context->CopyResource(copyTextureGame, backBuffer);

                                    ID3D10Texture2D *outputTexture = NULL;
                                    int lastRendered = -1;

                                    if(keyedMutexes[curCapture]->AcquireSync(0, 0) == WAIT_OBJECT_0)
                                        lastRendered = (int)curCapture;
                                    else if(keyedMutexes[nextCapture]->AcquireSync(0, 0) == WAIT_OBJECT_0)
                                        lastRendered = (int)nextCapture;

                                    if(lastRendered != -1)
                                    {
                                        shareDevice->CopyResource(sharedTextures[lastRendered], copyTextureIntermediary);
                                        keyedMutexes[lastRendered]->ReleaseSync(0);
                                    }

                                    texData->lastRendered = lastRendered;
                                    backBuffer->Release();
                                }

                                curCapture = nextCapture;
                            }
                        }
                    }
                }
                else
                    ClearD3D11Data();
            }

            device->Release();
            context->Release();
        }
    }

    gi11swapPresent.Unhook();
    HRESULT hRes = swap->Present(syncInterval, flags);
    gi11swapPresent.Rehook();

    return hRes;
}
Example #23
0
// set frontSurface to lpDDSurface if lpDDSurface is primary
// returns true if frontSurface is set
// returns false if frontSurface is NULL and lpDDSurface is not primary
bool getFrontSurface(LPDIRECTDRAWSURFACE7 lpDDSurface)
{
    //logOutput << CurrentTimeString() << "called getFrontSurface" << endl;

    if (!lpDDSurface)
    {
        //logOutput << CurrentTimeString() << "lpDDSurface null" << endl;
        return false;
    }

    if (!g_ddInterface)
    {
        LPDIRECTDRAWSURFACE7 dummy;
        if (lpDDSurface->QueryInterface(IID_IDirectDrawSurface7, (LPVOID*)&dummy) == S_OK)
        {
            IUnknown* Unknown;
            HRESULT err;
            if (FAILED(err = dummy->GetDDInterface((LPVOID*)&Unknown)))
            {
                logOutput << CurrentTimeString() << "getFrontSurface: could not get DirectDraw interface" << endl;
                printDDrawError(err, "getFrontSurface");
            }
            else
            {
                if (Unknown->QueryInterface(IID_IDirectDraw7, (LPVOID*)&g_ddInterface) == S_OK)
                {
                    logOutput << CurrentTimeString() << "Got DirectDraw interface pointer" << endl;
                }
                else
                {
                    logOutput << CurrentTimeString() << "Query of DirectDraw interface failed" << endl;
                }
            }
            ddrawSurfaceRelease.Unhook();
            dummy->Release();
            ddrawSurfaceRelease.Rehook();
        }
    }

    if (!bTargetAcquired)
    {
        DDSCAPS2 caps;
        if (SUCCEEDED(lpDDSurface->GetCaps(&caps)))
        {
            //logOutput << CurrentTimeString() << "checking if surface is primary" << endl;
            if (caps.dwCaps & DDSCAPS_PRIMARYSURFACE)
            {
                logOutput << CurrentTimeString() << "found primary surface" << endl;
                g_frontSurface = lpDDSurface;
                if (!SetupDDraw())
                {
                    return false;
                }
                else
                {
                    bTargetAcquired = true;
                }
            }
        }
        else
        {
            logOutput << CurrentTimeString() << "could not retrieve caps" << endl;
        }
    }

    return lpDDSurface == g_frontSurface;
}
Example #24
0
bool InitDDrawCapture()
{
    bool versionSupported = false;
    HMODULE hDDrawLib = NULL;
    if (hDDrawLib = GetModuleHandle(TEXT("ddraw.dll")))
    {
        bool isWinVistaMin = IsWindowsVistaOrGreater();
        bool isWin7min = IsWindows7OrGreater();
        bool isWin8min = IsWindows8OrGreater();

        UPARAM libBaseAddr = UPARAM(hDDrawLib);
        UPARAM surfCreateOffset;
        UPARAM surfUnlockOffset;
        UPARAM surfReleaseOffset;
        UPARAM surfRestoreOffset;
        UPARAM surfBltOffset;
        UPARAM surfFlipOffset;
        UPARAM surfSetPaletteOffset;
        UPARAM palSetEntriesOffset;

        if (isWinVistaMin)
        {
            if (!isWin7min)
            {
                RUNEVERYRESET logOutput << CurrentTimeString() << "Windows Vista not supported yet" << endl;
            }
            else if (isWin7min && !isWin8min)
            {
                surfCreateOffset = 0x617E;
                surfUnlockOffset = 0x4C40;
                surfReleaseOffset = 0x3239;
                surfRestoreOffset = 0x3E9CB;
                surfBltOffset = surfCreateOffset + 0x44F63;
                surfFlipOffset = surfCreateOffset + 0x37789;
                surfSetPaletteOffset = surfCreateOffset + 0x4D2D3;
                palSetEntriesOffset = surfCreateOffset + 0x4CE68;
                versionSupported = true;
            }
            else if (isWin8min)
            {
                surfCreateOffset = 0x9530 + 0xC00;
                surfUnlockOffset = surfCreateOffset + 0x2A1D0;
                surfReleaseOffset = surfCreateOffset - 0x1A80;
                surfRestoreOffset = surfCreateOffset + 0x36000;
                surfBltOffset = surfCreateOffset + 0x438DC;
                surfFlipOffset = surfCreateOffset + 0x33EF3;
                surfSetPaletteOffset = surfCreateOffset + 0x4D3B8;
                palSetEntriesOffset = surfCreateOffset + 0x4CF4C;
                versionSupported = false;	// some crash bugs remaining

                RUNEVERYRESET logOutput << CurrentTimeString() << "Windows 8 not supported yet" << endl;
            }
            else
            {
                RUNEVERYRESET logOutput << CurrentTimeString() << "Unknown OS version" << endl;
            }
        }
        else
        {
            RUNEVERYRESET logOutput << CurrentTimeString() << "OS version not supported" << endl;
        }

        if (versionSupported)
        {
            ddrawSurfaceCreate.Hook((FARPROC)(libBaseAddr + surfCreateOffset), (FARPROC)CreateSurface);
            ddrawSurfaceRestore.Hook((FARPROC)(libBaseAddr + surfRestoreOffset), (FARPROC)Restore);
            ddrawSurfaceRelease.Hook((FARPROC)(libBaseAddr + surfReleaseOffset), (FARPROC)Release);
            ddrawSurfaceUnlock.Hook((FARPROC)(libBaseAddr + surfUnlockOffset), (FARPROC)Unlock);
            ddrawSurfaceBlt.Hook((FARPROC)(libBaseAddr + surfBltOffset), (FARPROC)Blt);
            ddrawSurfaceFlip.Hook((FARPROC)(libBaseAddr + surfFlipOffset), (FARPROC)Flip);
            ddrawSurfaceSetPalette.Hook((FARPROC)(libBaseAddr + surfSetPaletteOffset), (FARPROC)SetPalette);
            ddrawPaletteSetEntries.Hook((FARPROC)(libBaseAddr + palSetEntriesOffset), (FARPROC)PaletteSetEntries);

            ddrawSurfaceUnlock.Rehook();
            ddrawSurfaceFlip.Rehook();
            ddrawSurfaceBlt.Rehook();
            /*
            ddrawSurfaceCreate.Rehook();
            ddrawSurfaceRestore.Rehook();
            ddrawSurfaceRelease.Rehook();
            ddrawSurfaceSetPalette.Rehook();
            ddrawPaletteSetEntries.Rehook();
            */
        }
    }

    return versionSupported;
}
Example #25
0
void CaptureDDraw()
{
    //RUNEVERYRESET logOutput << CurrentTimeString() << "called CaptureDDraw()" << endl;

    if (bCapturing && WaitForSingleObject(hSignalEnd, 0) == WAIT_OBJECT_0)
    {
        //logOutput << CurrentTimeString() << "not capturing or received hSignalEnd" << endl;
        bStopRequested = true;
    }

    if (bCapturing && !IsWindow(hwndOBS))
    {
        //logOutput << CurrentTimeString() << "not capturing or OBS window not found" << endl;
        hwndOBS = NULL;
        bStopRequested = true;
    }

    if (bStopRequested)
    {
        CleanUpDDraw();
        bCapturing = false;
        bStopRequested = false;
    }

    if (!bCapturing && WaitForSingleObject(hSignalRestart, 0) == WAIT_OBJECT_0)
    {
        //logOutput << CurrentTimeString() << "capturing and received hSignalRestart" << endl;
        hwndOBS = FindWindow(OBS_WINDOW_CLASS, NULL);
        if (hwndOBS) {
            logOutput << CurrentTimeString() << "received restart event, capturing" << endl;
            bCapturing = true;
        }
        else {
            logOutput << CurrentTimeString() << "received restart event, but couldn't find window" << endl;
        }
    }

    LONGLONG timeVal = OSGetTimeMicroseconds();

    //check keep alive state, dumb but effective
    if (bCapturing)
    {
        if (!keepAliveTime)
            keepAliveTime = timeVal;

        if ((timeVal - keepAliveTime) > 5000000)
        {
            HANDLE hKeepAlive = OpenEvent(EVENT_ALL_ACCESS, FALSE, strKeepAlive.c_str());
            if (hKeepAlive) {
                CloseHandle(hKeepAlive);
            }
            else {
                logOutput << CurrentTimeString() << "Keepalive no longer found on ddraw, freeing capture data" << endl;
                CleanUpDDraw();
                bCapturing = false;
            }

            keepAliveTime = timeVal;
        }
    }

    if (bHasTextures)
    {
        LONGLONG frameTime;
        if (bCapturing)
        {
            if (copyData)
            {
                if (frameTime = copyData->frameTime)
                {
                    LONGLONG timeElapsed = timeVal - lastTime;

                    if (timeElapsed >= frameTime)
                    {
                        lastTime += frameTime;
                        if (timeElapsed > frameTime * 2)
                            lastTime = timeVal;


                        //logOutput << CurrentTimeString() << "CaptureDDraw: capturing screen from 0x" << g_frontSurface << endl;

                        HRESULT hr;
                        ddrawSurfaceBlt.Unhook();
                        hr = ddCaptures[curCapture]->Blt(NULL, g_frontSurface, NULL, DDBLT_ASYNC, NULL);
                        ddrawSurfaceBlt.Rehook();
                        if (SUCCEEDED(hr))
                        {
                            DWORD nextCapture = (curCapture == NUM_BUFFERS - 1) ? 0 : (curCapture + 1);
                            curCPUTexture = curCapture;
                            curCapture = nextCapture;

                            SetEvent(hCopyEvent);
                        }
                        else
                        {
                            printDDrawError(hr, "CaptureDDraw");
                        }
                        //logOutput << CurrentTimeString() << "CaptureDDraw: finished capturing" << endl;
                    }
                }
            }
        }
    }
}
Example #26
0
void CleanUpDDraw()
{
    logOutput << CurrentTimeString() << "Cleaning up" << endl;
    if (copyData)
        copyData->lastRendered = -1;

    if (hCopyThread)
    {
        bKillThread = true;
        SetEvent(hCopyEvent);
        if (WaitForSingleObject(hCopyThread, 500) != WAIT_OBJECT_0)
            TerminateThread(hCopyThread, -1);

        CloseHandle(hCopyThread);
        CloseHandle(hCopyEvent);

        hCopyThread = NULL;
        hCopyEvent = NULL;
    }

    ddrawSurfaceRelease.Unhook();
    for (int i = 0; i < NUM_BUFFERS; i++)
    {
        if (ddCaptures[i])
        {
            ddCaptures[i]->Release();
            ddCaptures[i] = NULL;
        }
    }
    ddrawSurfaceRelease.Rehook();

    DestroySharedMemory();

    bHasTextures = false;
    curCapture = 0;
    curCPUTexture = 0;
    keepAliveTime = 0;
    resetCount++;
    copyWait = 0;
    lastTime = 0;
    g_frontSurface = NULL;
    g_bUseFlipMethod = false;
    bTargetAcquired = false;
    g_dwSize = 0;
    g_bUse32bitCapture = false;
    g_bConvert16to32 = false;
    g_bUsePalette = false;
    g_dwCaptureSize = 0;

    if (g_ddInterface)
    {
        g_ddInterface->Release();
        g_ddInterface = NULL;
    }

    g_CurrentPalette.Free();

    if (g_surfaceDesc)
        delete g_surfaceDesc;
    g_surfaceDesc = NULL;

    if (ddUnlockFctMutex)
    {
        CloseHandle(ddUnlockFctMutex);
        ddUnlockFctMutex = 0;
    }

    //UnhookAll();

    logOutput << CurrentTimeString() << "---------------------- Cleared DirectDraw Capture ----------------------" << endl;
}
Example #27
0
void FreeGLCapture()
{
    glHookSwapBuffers.Unhook();
    glHookSwapLayerBuffers.Unhook();
    glHookDeleteContext.Unhook();
}
Example #28
0
bool InitGLCapture()
{
    bool bSuccess = false;

    HMODULE hGL = GetModuleHandle(TEXT("opengl32.dll"));
    if(hGL)
    {
        pglReadBuffer       = (GLREADBUFFERPROC)        GetProcAddress(hGL, "glReadBuffer");
        pglReadPixels       = (GLREADPIXELSPROC)        GetProcAddress(hGL, "glReadPixels");
        pglGetError         = (GLGETERRORPROC)          GetProcAddress(hGL, "glGetError");
        pwglSwapLayerBuffers= (WGLSWAPLAYERBUFFERSPROC) GetProcAddress(hGL, "wglSwapLayerBuffers");
        pwglDeleteContext   = (WGLDELETECONTEXTPROC)    GetProcAddress(hGL, "wglDeleteContext");
        pwglGetProcAddress  = (WGLGETPROCADDRESSPROC)   GetProcAddress(hGL, "wglGetProcAddress");
        pwglMakeCurrent     = (WGLMAKECURRENTPROC)      GetProcAddress(hGL, "wglMakeCurrent");
        pwglCreateContext   = (WGLCREATECONTEXTPROC)    GetProcAddress(hGL, "wglCreateContext");

        if( !pglReadBuffer || !pglReadPixels || !pglGetError || !pwglSwapLayerBuffers || !pwglDeleteContext || 
            !pwglGetProcAddress || !pwglMakeCurrent || !pwglCreateContext)
        {
            return false;
        }

        HDC hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
        if(hDC)
        {
            PIXELFORMATDESCRIPTOR pfd;
            ZeroMemory(&pfd, sizeof(pfd));
            pfd.nSize = sizeof(pfd);
            pfd.nVersion = 1;
            pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
            pfd.iPixelType = PFD_TYPE_RGBA;
            pfd.cColorBits = 32;
            pfd.cDepthBits = 32;
            pfd.cAccumBits = 32;
            pfd.iLayerType = PFD_MAIN_PLANE;
            SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd), &pfd);

            HGLRC hGlrc = jimglCreateContext(hDC);
            if(hGlrc)
            {
                jimglMakeCurrent(hDC, hGlrc);

                pglBufferData       = (GLBUFFERDATAARBPROC)     jimglGetProcAddress("glBufferData");
                pglDeleteBuffers    = (GLDELETEBUFFERSARBPROC)  jimglGetProcAddress("glDeleteBuffers");
                pglGenBuffers       = (GLGENBUFFERSARBPROC)     jimglGetProcAddress("glGenBuffers");
                pglMapBuffer        = (GLMAPBUFFERPROC)         jimglGetProcAddress("glMapBuffer");
                pglUnmapBuffer      = (GLUNMAPBUFFERPROC)       jimglGetProcAddress("glUnmapBuffer");
                pglBindBuffer       = (GLBINDBUFFERPROC)        jimglGetProcAddress("glBindBuffer");

                UINT lastErr = GetLastError();

                if(pglBufferData && pglDeleteBuffers && pglGenBuffers && pglMapBuffer && pglUnmapBuffer && pglBindBuffer)
                {
                    glHookSwapBuffers.Hook((FARPROC)SwapBuffers, (FARPROC)SwapBuffersHook);
                    glHookSwapLayerBuffers.Hook((FARPROC)jimglSwapLayerBuffers, (FARPROC)wglSwapLayerBuffersHook);
                    glHookDeleteContext.Hook((FARPROC)jimglDeleteContext, (FARPROC)wglDeleteContextHook);
                    bSuccess = true;
                }

                jimglMakeCurrent(NULL, NULL);

                jimglDeleteContext(hGlrc);

                if(bSuccess)
                {
                    glHookSwapBuffers.Rehook();
                    glHookSwapLayerBuffers.Rehook();
                    glHookDeleteContext.Rehook();
                }
            }

            DeleteDC(hDC);
        }
    }

    return bSuccess;
}
Example #29
0
bool InitGLCapture()
{
    static HWND hwndOpenGLSetupWindow = NULL;
    bool bSuccess = false;

    if(!hwndOpenGLSetupWindow)
    {
        WNDCLASSEX windowClass;

        ZeroMemory(&windowClass, sizeof(windowClass));

        windowClass.cbSize = sizeof(windowClass);
        windowClass.style = CS_OWNDC;
        windowClass.lpfnWndProc = DefWindowProc;
        windowClass.lpszClassName = TEXT("OBSOGLHookClass");
        windowClass.hInstance = hinstMain;

        if(RegisterClassEx(&windowClass))
        {
            hwndOpenGLSetupWindow = CreateWindowEx (0,
                TEXT("OBSOGLHookClass"),
                TEXT("OBS OpenGL Context Window"),
                WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
                0, 0,
                1, 1,
                NULL,
                NULL,
                hinstMain,
                NULL
                );
        }
    }

    HMODULE hGL = GetModuleHandle(TEXT("opengl32.dll"));
    if(hGL && hwndOpenGLSetupWindow)
    {
        pglReadBuffer       = (GLREADBUFFERPROC)        GetProcAddress(hGL, "glReadBuffer");
        pglReadPixels       = (GLREADPIXELSPROC)        GetProcAddress(hGL, "glReadPixels");
        pglGetError         = (GLGETERRORPROC)          GetProcAddress(hGL, "glGetError");
        pwglSwapLayerBuffers= (WGLSWAPLAYERBUFFERSPROC) GetProcAddress(hGL, "wglSwapLayerBuffers");
        pwglSwapBuffers=      (WGLSWAPBUFFERSPROC)      GetProcAddress(hGL, "wglSwapBuffers");
        pwglDeleteContext   = (WGLDELETECONTEXTPROC)    GetProcAddress(hGL, "wglDeleteContext");
        pwglGetProcAddress  = (WGLGETPROCADDRESSPROC)   GetProcAddress(hGL, "wglGetProcAddress");
        pwglMakeCurrent     = (WGLMAKECURRENTPROC)      GetProcAddress(hGL, "wglMakeCurrent");
        pwglCreateContext   = (WGLCREATECONTEXTPROC)    GetProcAddress(hGL, "wglCreateContext");

        if( !pglReadBuffer || !pglReadPixels || !pglGetError || !pwglSwapLayerBuffers || !pwglSwapBuffers ||
            !pwglDeleteContext || !pwglGetProcAddress || !pwglMakeCurrent || !pwglCreateContext)
        {
            return false;
        }

        HDC hDC = GetDC(hwndOpenGLSetupWindow);
        if(hDC)
        {
            PIXELFORMATDESCRIPTOR pfd;
            ZeroMemory(&pfd, sizeof(pfd));
            pfd.nSize = sizeof(pfd);
            pfd.nVersion = 1;
            pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_GENERIC_ACCELERATED;
            pfd.iPixelType = PFD_TYPE_RGBA;
            pfd.cColorBits = 32;
            pfd.cDepthBits = 32;
            pfd.cAccumBits = 32;
            pfd.iLayerType = PFD_MAIN_PLANE;
            SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd), &pfd);

            HGLRC hGlrc = jimglCreateContext(hDC);
            if(hGlrc)
            {
                jimglMakeCurrent(hDC, hGlrc);

                pglBufferData       = (GLBUFFERDATAARBPROC)     jimglGetProcAddress("glBufferData");
                pglDeleteBuffers    = (GLDELETEBUFFERSARBPROC)  jimglGetProcAddress("glDeleteBuffers");
                pglGenBuffers       = (GLGENBUFFERSARBPROC)     jimglGetProcAddress("glGenBuffers");
                pglMapBuffer        = (GLMAPBUFFERPROC)         jimglGetProcAddress("glMapBuffer");
                pglUnmapBuffer      = (GLUNMAPBUFFERPROC)       jimglGetProcAddress("glUnmapBuffer");
                pglBindBuffer       = (GLBINDBUFFERPROC)        jimglGetProcAddress("glBindBuffer");

                UINT lastErr = GetLastError();

                if(pglBufferData && pglDeleteBuffers && pglGenBuffers && pglMapBuffer && pglUnmapBuffer && pglBindBuffer)
                {
                    glHookSwapBuffers.Hook((FARPROC)SwapBuffers, (FARPROC)SwapBuffersHook);
                    glHookSwapLayerBuffers.Hook((FARPROC)jimglSwapLayerBuffers, (FARPROC)wglSwapLayerBuffersHook);
                    glHookwglSwapBuffers.Hook((FARPROC)jimglSwapBuffers, (FARPROC)wglSwapBuffersHook);
                    glHookDeleteContext.Hook((FARPROC)jimglDeleteContext, (FARPROC)wglDeleteContextHook);
                    bSuccess = true;
                }

                jimglMakeCurrent(NULL, NULL);

                jimglDeleteContext(hGlrc);

                ReleaseDC(hwndOpenGLSetupWindow, hDC);

                if(bSuccess)
                {
                    glHookSwapBuffers.Rehook();
                    glHookSwapLayerBuffers.Rehook();
                    glHookwglSwapBuffers.Rehook();
                    glHookDeleteContext.Rehook();

                    DestroyWindow(hwndOpenGLSetupWindow);
                    hwndOpenGLSetupWindow = NULL;

                    UnregisterClass(TEXT("OBSOGLHookClass"), hinstMain);
                }
            }

            if(hwndOpenGLSetupWindow)
                ReleaseDC(hwndOpenGLSetupWindow, hDC);
        }
    }

    return bSuccess;
}
Example #30
-1
    HRESULT STDMETHODCALLTYPE SwapResizeBuffersHook(UINT bufferCount, UINT width, UINT height, DXGI_FORMAT giFormat, UINT flags)
    {
        IDXGISwapChain *swap = (IDXGISwapChain*)this;

        gi11swapResizeBuffers.Unhook();
        HRESULT hRes = swap->ResizeBuffers(bufferCount, width, height, giFormat, flags);
        gi11swapResizeBuffers.Rehook();

        if(lpCurrentSwap == NULL && !bTargetAcquired)
        {
            lpCurrentSwap = swap;
            bTargetAcquired = true;
        }

        if(lpCurrentSwap == swap)
            SetupD3D11(swap);

        return hRes;
    }