HRESULT APIENTRY OVRCreateDXGIFactory2(
	__in   UINT flags,
	__in   const IID &riid,
	__out  void **ppFactory
	)
{
	HRESULT result = E_FAIL;

	restoreFunction( (PROC)oldCreateDXGIFactory2, oldCreateDXGIFactory2Data );

    if (IN_COMPATIBILITY_MODE())
    {
        result = (*oldCreateDXGIFactory2)(flags, riid, ppFactory);
    }
    else
    {
        WinCreateDXGIFactory2 createFunction = (WinCreateDXGIFactory2)GetProcAddress(rtFilterModule, "CreateDXGIFactory2");
        result = (*createFunction)(flags, riid, ppFactory);
    }

	setFunction( (PROC)oldCreateDXGIFactory2, (PROC)OVRCreateDXGIFactory2, oldCreateDXGIFactory2Data );

	printf("%s result 0x%x\n", __FUNCTION__, result);

	return result;
}
HRESULT APIENTRY OVRCreateDXGIFactory1(
	__in   REFIID riid,
	__out  void **ppFactory
	)
{
	HRESULT result = E_FAIL;

	restoreFunction( (PROC)oldCreateDXGIFactory1, oldCreateDXGIFactory1Data );

    if (IN_COMPATIBILITY_MODE())
    {
        result = (*oldCreateDXGIFactory1)(riid, ppFactory);
    }
    else
    {
        WinCreateDXGIFactory1 createFunction = (WinCreateDXGIFactory1)GetProcAddress(rtFilterModule, "CreateDXGIFactory1");
        result = (*createFunction)(riid, ppFactory);
    }

	setFunction( (PROC)oldCreateDXGIFactory1, (PROC)OVRCreateDXGIFactory1, oldCreateDXGIFactory1Data );

	printf("%s result 0x%x\n", __FUNCTION__, result);

	return result;
}
static HMODULE createShim( LPCSTR lpLibFileName, OVRTargetAPI targetAPI )
{
	//Sleep(10000);
	if( IN_COMPATIBILITY_MODE() )
	{
		return (*oldProcA)( lpLibFileName );
	}

	UNREFERENCED_PARAMETER( targetAPI );

	HMODULE result = NULL;

	result = (*oldProcA)( UMFilter );

	if( result )
	{
		PreloadLibraryFn loadFunc = (PreloadLibraryFn)GetProcAddress( result, "PreloadLibrary" );
		if( loadFunc )
		{
			HRESULT localRes = (*loadFunc)( oldProcA, lpLibFileName, &appDriver );
			if( localRes != S_OK )
				result = NULL;
		}
	}

	if( !result )
	{
		OutputDebugString( L"createShim:  unable to load usermode filter\n" );
		result = (*oldProcA)( lpLibFileName );
	}
	return result;
}
static HMODULE createShim( LPCSTR lpLibFileName, OVRTargetAPI targetAPI )
{
	//Sleep(10000);
	if( IN_COMPATIBILITY_MODE() )
	{
		return (*oldProcA)( lpLibFileName );
	}

	UNREFERENCED_PARAMETER( targetAPI );

	HMODULE result = NULL;

	result = (*oldProcA)( UMFilter );

	if( result )
	{
		PreloadLibraryFn loadFunc = (PreloadLibraryFn)GetProcAddress( result, "PreloadLibrary" );
		if( loadFunc )
		{
			HRESULT localRes = (*loadFunc)( oldProcA, lpLibFileName, &appDriver );
			if( localRes != S_OK )
				result = NULL;
		}
	}

	if( !result )
	{
        MessageBox(nullptr, L"Unable to find the Rift Display Driver.", L"Configuration Error", MB_OK | MB_ICONERROR);
		result = (*oldProcA)( lpLibFileName );
	}
	return result;
}
HRESULT APIENTRY OVRDirect3DCreate9Ex(UINT SDKVersion, void** aDevice)
{
	apiVersion = 9;

	HRESULT result = S_OK;

	restoreFunction( (PROC)oldDirectX9ExCreate, oldDirectX9ExCreateData );

    if (IN_COMPATIBILITY_MODE())
    {
        result = (*oldDirectX9ExCreate)(SDKVersion, aDevice);
    }
    else
    {
        WinDirect3DCreate9Ex createFunction = (WinDirect3DCreate9Ex)GetProcAddress(rtFilterModule, "Direct3DCreate9Ex");
        result = (*createFunction)(SDKVersion, aDevice);
    }

	setFunction( (PROC)oldDirectX9ExCreate, (PROC)OVRDirect3DCreate9Ex, oldDirectX9ExCreateData );

	printf("%s result 0x%x\n", __FUNCTION__, result);

	return result;
}