Exemplo n.º 1
0
bool TestDX11Present()
{
	HMODULE hD3D11 = LoadLibrary("d3d11.dll");

	if (!hD3D11)
	{
		Msg("* DX11: failed to load d3d11.dll");
		return false;
	}

	FuncPtrD3D11CreateDeviceAndSwapChain pD3D11CreateDeviceAndSwapChain = 
		(FuncPtrD3D11CreateDeviceAndSwapChain)GetProcAddress(hD3D11, "D3D11CreateDeviceAndSwapChain");

	if (!pD3D11CreateDeviceAndSwapChain)
	{
		Msg("* DX11: failed to get address of D3D11CreateDeviceAndSwapChain");
		return false;
	}

	// Register class
	WNDCLASSEX wcex;
	ZeroMemory(&wcex, sizeof(wcex));
	wcex.cbSize = sizeof( WNDCLASSEX );
	wcex.lpfnWndProc = WndProc;
	wcex.hInstance = GetModuleHandle(NULL);
	wcex.lpszClassName = "TestDX11WindowClass";
	if( !RegisterClassEx( &wcex ) )
	{
		Msg("* DX11: failed to register window class");
		return false;
	}

	// Create window
	HWND hWnd = CreateWindow( "TestDX11WindowClass", "",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, NULL, NULL, NULL );

	DXGI_SWAP_CHAIN_DESC sd;

	if (!hWnd)
	{
		Msg("* DX11: failed to create window");
		return false;
	}

	HRESULT hr = E_FAIL;

	ZeroMemory( &sd, sizeof( sd ) );
	sd.BufferCount = 1;
	sd.BufferDesc.Width = 800;
	sd.BufferDesc.Height = 600;
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow = hWnd;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.Windowed = TRUE;

	D3D_FEATURE_LEVEL pFeatureLevels[] = {D3D_FEATURE_LEVEL_11_0};
	D3D_FEATURE_LEVEL FeatureLevel;

	ID3D11Device*           pd3dDevice = NULL;
	ID3D11DeviceContext*    pContext = NULL;
	IDXGISwapChain*         pSwapChain = NULL;

	hr = pD3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, pFeatureLevels, 1,
		D3D11_SDK_VERSION, &sd, &pSwapChain, &pd3dDevice, &FeatureLevel, &pContext );

	if (FAILED(hr))
		Msg("* D3D11: device creation failed with hr=0x%08x", hr);

	if (pContext) pContext->Release();
	if (pSwapChain) pSwapChain->Release();
	if (pd3dDevice) pd3dDevice->Release();
	
	FreeLibrary(hD3D11);
	
	DestroyWindow(hWnd);

	return SUCCEEDED(hr);
}
Exemplo n.º 2
0
/// Prepares DXGI and D3D11 data by trying to determine the module filepath
/// and function offsets in memory.
/// (This data can later be used for hooking / code injection.)
///
/// Adjusts the data behind the global variables dxgi and d3d11.
void PrepareDXGI11(IDXGIAdapter1* pAdapter, bool initializeDXGIData) {

	if (!dxgi || !d3d11 || !pAdapter)
		return;

	ods("D3D11: Preparing static data for DXGI and D3D11 Injection");

	d3d11->wcFileName[0] = 0;
	d3d11->iOffsetAddRef = 0;
	d3d11->iOffsetRelease = 0;

	HMODULE hD3D11 = LoadLibrary("D3D11.DLL");

	if (hD3D11 != NULL) {

		HWND hwnd = CreateWindowW(L"STATIC", L"Mumble DXGI Window", WS_OVERLAPPEDWINDOW,
								  CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 0,
								  NULL, NULL, 0);

		D3D11CreateDeviceAndSwapChainType pD3D11CreateDeviceAndSwapChain = reinterpret_cast<D3D11CreateDeviceAndSwapChainType>(GetProcAddress(hD3D11, "D3D11CreateDeviceAndSwapChain"));

		DXGI_SWAP_CHAIN_DESC desc;
		ZeroMemory(&desc, sizeof(desc));

		RECT rcWnd;
		BOOL success = GetClientRect(hwnd, &rcWnd);
		if (success) {
			desc.BufferDesc.Width = rcWnd.right - rcWnd.left;
			desc.BufferDesc.Height = rcWnd.bottom - rcWnd.top;

			ods("D3D11: Got ClientRect W %d H %d", desc.BufferDesc.Width, desc.BufferDesc.Height);

			desc.BufferDesc.RefreshRate.Numerator = 60;
			desc.BufferDesc.RefreshRate.Denominator = 1;
			desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
			desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
			desc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;

			desc.SampleDesc.Count = 1;
			desc.SampleDesc.Quality = 0;

			desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;

			desc.BufferCount = 2;

			desc.OutputWindow = hwnd;

			desc.Windowed = true;

			desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

			IDXGISwapChain *pSwapChain = NULL;
			ID3D11Device *pDevice = NULL;
			D3D_FEATURE_LEVEL featureLevel;
			ID3D11DeviceContext *pDeviceContext = NULL;
			HRESULT hr = pD3D11CreateDeviceAndSwapChain(pAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &desc, &pSwapChain, &pDevice, &featureLevel, &pDeviceContext);
			if (FAILED(hr))
				ods("D3D11: pD3D11CreateDeviceAndSwapChain failure!");

			if (pDevice && pDeviceContext && pSwapChain) {

				// For VC++ the vtable is located at the base addr. of the object and each function entry is a single pointer. Since p.e. the base classes
				// of IDXGISwapChain have a total of 8 functions the 8+Xth entry points to the Xth added function in the derived interface.

				void ***vtbl = (void ***) pSwapChain;

				void *pPresent = (*vtbl)[8];
				int offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pPresent), dxgi->wcFileName, ARRAY_NUM_ELEMENTS(dxgi->wcFileName), "D3D11", "Present");
				if (offset >= 0) {
					if (initializeDXGIData) {
						dxgi->iOffsetPresent = offset;
						ods("D3D11: Successfully found Present offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetPresent);
					} else {
						if (dxgi->iOffsetPresent == offset) {
							ods("D3D11: Successfully verified Present offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetPresent);
						} else {
							ods("D3D11: Failed to verify Present offset for %ls. Found %d, but previously found %d.", dxgi->wcFileName, offset, dxgi->iOffsetPresent);
						}
					}
				}

				void *pResize = (*vtbl)[13];
				offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pResize), dxgi->wcFileName, ARRAY_NUM_ELEMENTS(dxgi->wcFileName), "D3D11", "ResizeBuffers");
				if (offset >= 0) {
					if (initializeDXGIData) {
						dxgi->iOffsetResize = offset;
						ods("D3D11: Successfully found ResizeBuffers offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetResize);
					} else {
						if (dxgi->iOffsetResize == offset) {
							ods("D3D11: Successfully verified ResizeBuffers offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetResize);
						} else {
							ods("D3D11: Failed to verify ResizeBuffers offset for %ls. Found %d, but previously found %d.", dxgi->wcFileName, offset, dxgi->iOffsetResize);
						}
					}
				}

				vtbl = (void ***) pDevice;

				void *pAddRef = (*vtbl)[1];
				offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pAddRef), d3d11->wcFileName, ARRAY_NUM_ELEMENTS(d3d11->wcFileName), "D3D11", "AddRef");
				if (offset >= 0) {
					d3d11->iOffsetAddRef = offset;
					ods("D3D11: Successfully found AddRef offset: %ls: %d", d3d11->wcFileName, d3d11->iOffsetAddRef);
				}

				void *pRelease = (*vtbl)[2];
				offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pRelease), d3d11->wcFileName, ARRAY_NUM_ELEMENTS(d3d11->wcFileName), "D3D11", "Release");
				if (offset >= 0) {
					d3d11->iOffsetRelease = offset;
					ods("D3D11: Successfully found Release offset: %ls: %d", d3d11->wcFileName, d3d11->iOffsetRelease);
				}
			}

			if (pDevice)
				pDevice->Release();
			if (pDeviceContext)
				pDeviceContext->Release();
			if (pSwapChain)
				pSwapChain->Release();

		} else {
			FreeLibrary(hD3D11);
		}

		DestroyWindow(hwnd);
	} else {
		FreeLibrary(hD3D11);
	}
}