* Implemented IDirect3D9's GetAdapterCount() and GetAdapterIdentifier()

* Made d3d9.dll compile with MSVC

svn path=/trunk/; revision=32122
This commit is contained in:
Gregor Brunmar 2008-02-04 21:33:12 +00:00
parent 817d9a0beb
commit db26f5d219
9 changed files with 294 additions and 32 deletions

View file

@ -0,0 +1,156 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS ReactX
* FILE: dll/directx/d3d9/adapter.c
* PURPOSE: d3d9.dll adapter info functions
* PROGRAMERS: Gregor Brunmar <gregor (dot) brunmar (at) home (dot) se>
*/
#include "d3d9_common.h"
#include <d3d9.h>
#include <ddraw.h>
#include <strsafe.h>
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
typedef BOOL (WINAPI *LPFN_DISABLEWOW64FSREDIRECTION) (PVOID*);
typedef BOOL (WINAPI *LPFN_REVERTWOW64FSREDIRECTION) (PVOID);
static BOOL GetDriverName(LPDISPLAY_DEVICEA pDisplayDevice, D3DADAPTER_IDENTIFIER9* pIdentifier)
{
HKEY hKey;
BOOL bResult = FALSE;
if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_LOCAL_MACHINE, pDisplayDevice->DeviceKey + strlen("\\Registry\\Machine\\"), 0, KEY_QUERY_VALUE, &hKey))
{
DWORD DriverNameLength = MAX_DEVICE_IDENTIFIER_STRING - (DWORD)strlen(".dll");
DWORD Type = 0;
if (ERROR_SUCCESS == RegQueryValueExA(hKey, "InstalledDisplayDrivers", 0, &Type, (LPBYTE)pIdentifier->Driver, &DriverNameLength))
{
pIdentifier->Driver[DriverNameLength] = '\0';
StringCbCatA(pIdentifier->Driver, MAX_DEVICE_IDENTIFIER_STRING, ".dll");
bResult = TRUE;
}
RegCloseKey(hKey);
}
return bResult;
}
static void GetDriverVersion(LPDISPLAY_DEVICEA pDisplayDevice, D3DADAPTER_IDENTIFIER9* pIdentifier)
{
HMODULE hModule;
LPFN_ISWOW64PROCESS fnIsWow64Process;
BOOL bIsWow64 = FALSE;
PVOID OldWow64RedirectValue;
UINT DriverFileSize;
hModule = GetModuleHandleA("KERNEL32");
fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(hModule, "IsWow64Process");
if (fnIsWow64Process)
{
fnIsWow64Process(GetCurrentProcess(), &bIsWow64);
if (bIsWow64)
{
LPFN_DISABLEWOW64FSREDIRECTION fnDisableWow64FsRedirection;
fnDisableWow64FsRedirection = (LPFN_DISABLEWOW64FSREDIRECTION)GetProcAddress(hModule, "Wow64DisableWow64FsRedirection");
fnDisableWow64FsRedirection(&OldWow64RedirectValue);
}
}
DriverFileSize = GetFileVersionInfoSizeA(pIdentifier->Driver, NULL);
if (DriverFileSize > 0)
{
VS_FIXEDFILEINFO* FixedFileInfo = NULL;
LPVOID pBlock = LocalAlloc(LMEM_ZEROINIT, DriverFileSize);
if (TRUE == GetFileVersionInfoA(pIdentifier->Driver, 0, DriverFileSize, pBlock))
{
if (TRUE == VerQueryValueA(pBlock, "\\", (LPVOID*)&FixedFileInfo, &DriverFileSize))
{
pIdentifier->DriverVersion.HighPart = FixedFileInfo->dwFileVersionMS;
pIdentifier->DriverVersion.LowPart = FixedFileInfo->dwFileVersionLS;
}
}
LocalFree(pBlock);
}
if (bIsWow64)
{
LPFN_REVERTWOW64FSREDIRECTION fnRevertWow64FsRedirection;
fnRevertWow64FsRedirection = (LPFN_REVERTWOW64FSREDIRECTION)GetProcAddress(hModule, "Wow64RevertWow64FsRedirection");
fnRevertWow64FsRedirection(&OldWow64RedirectValue);
}
}
static void ParseField(LPCSTR lpszDeviceKey, LPDWORD pField, LPCSTR lpszSubString)
{
const char* ResultStr;
ResultStr = strstr(lpszDeviceKey, lpszSubString);
if (ResultStr != NULL)
{
*pField = strtol(ResultStr + strlen(lpszSubString), NULL, 16);
}
}
static void GetDeviceId(LPCSTR lpszDeviceKey, D3DADAPTER_IDENTIFIER9* pIdentifier)
{
ParseField(lpszDeviceKey, &pIdentifier->VendorId, "VEN_");
ParseField(lpszDeviceKey, &pIdentifier->DeviceId, "DEV_");
ParseField(lpszDeviceKey, &pIdentifier->SubSysId, "SUBSYS_");
ParseField(lpszDeviceKey, &pIdentifier->Revision, "REV_");
}
static void GenerateDeviceIdentifier(D3DADAPTER_IDENTIFIER9* pIdentifier)
{
DWORD* dwIdentifier = (DWORD*)&pIdentifier->DeviceIdentifier;
pIdentifier->DeviceIdentifier = CLSID_DirectDraw;
dwIdentifier[0] ^= pIdentifier->VendorId;
dwIdentifier[1] ^= pIdentifier->DeviceId;
dwIdentifier[2] ^= pIdentifier->SubSysId;
dwIdentifier[3] ^= pIdentifier->Revision;
dwIdentifier[2] ^= pIdentifier->DriverVersion.LowPart;
dwIdentifier[3] ^= pIdentifier->DriverVersion.HighPart;
}
BOOL GetAdapterInfo(LPCSTR lpszDeviceName, D3DADAPTER_IDENTIFIER9* pIdentifier)
{
DISPLAY_DEVICEA DisplayDevice;
DWORD AdapterIndex;
BOOL FoundDisplayDevice;
memset(&DisplayDevice, 0, sizeof(DISPLAY_DEVICEA));
DisplayDevice.cb = sizeof(DISPLAY_DEVICEA);
AdapterIndex = 0;
FoundDisplayDevice = FALSE;
while (EnumDisplayDevicesA(NULL, AdapterIndex, &DisplayDevice, 0) == TRUE)
{
if (_stricmp(lpszDeviceName, DisplayDevice.DeviceName) == 0)
{
FoundDisplayDevice = TRUE;
break;
}
}
/* No matching display device found? */
if (FALSE == FoundDisplayDevice)
return FALSE;
lstrcpynA(pIdentifier->Description, DisplayDevice.DeviceString, MAX_DEVICE_IDENTIFIER_STRING);
lstrcpynA(pIdentifier->DeviceName, DisplayDevice.DeviceName, CCHDEVICENAME);
if (GetDriverName(&DisplayDevice, pIdentifier) == TRUE)
GetDriverVersion(&DisplayDevice, pIdentifier);
GetDeviceId(DisplayDevice.DeviceID, pIdentifier);
GenerateDeviceIdentifier(pIdentifier);
return TRUE;
}

View file

@ -0,0 +1,14 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS ReactX
* FILE: dll/directx/d3d9/adapter.h
* PURPOSE: d3d9.dll adapter info functions
* PROGRAMERS: Gregor Brunmar <gregor (dot) brunmar (at) home (dot) se>
*/
#ifndef _ADAPTER_H_
#define _ADAPTER_H_
BOOL GetAdapterInfo(LPCSTR lpszDeviceName, D3DADAPTER_IDENTIFIER9* pIdentifier);
#endif

View file

@ -10,10 +10,12 @@
<library>uuid</library>
<library>dxguid</library>
<library>strsafe</library>
<library>version</library>
<file>d3d9.c</file>
<file>d3d9_helpers.c</file>
<file>d3d9_impl.c</file>
<file>d3d9_create.c</file>
<file>adapter.c</file>
<file>d3d9.rc</file>
</module>

View file

@ -14,6 +14,6 @@
#define DLLAPI __declspec(dllexport)
#define DX_D3D9_DEBUG 0x80000000
extern const struct IDirect3D9Vtbl Direct3D9_Vtbl;
extern struct IDirect3D9Vtbl Direct3D9_Vtbl;
#endif // _D3D9_COMMON_H_

View file

@ -46,31 +46,46 @@ static VOID SetAdapterInfo(IN OUT LPDIRECT3D9_DISPLAYADAPTER_INT pDisplayAdapter
pDisplayAdapter->bInUseFlag = TRUE;
}
static BOOL GetDirect3DAdapterInfo(IN OUT LPDIRECT3D9_DISPLAYADAPTER_INT pDisplayAdapter)
{
HDC hDC;
/* Check if minimum DirectDraw is supported */
if (IsDirectDrawSupported() == FALSE)
return FALSE;
/* Test DC creation for the display device */
if (NULL == (hDC = CreateDCA(NULL, pDisplayAdapter->szDeviceName, NULL, NULL)))
return FALSE;
DeleteDC(hDC);
return TRUE;
}
static BOOL GetDisplayDeviceInfo(IN OUT LPDIRECT3D9_INT pDirect3D9)
{
DISPLAY_DEVICEA DisplayDevice;
DWORD AdapterIndex;
HDC hDC;
memset(&DisplayDevice, 0, sizeof(DISPLAY_DEVICEA));
DisplayDevice.cb = sizeof(DISPLAY_DEVICEA);
pDirect3D9->dwNumDisplayAdapters = 0;
pDirect3D9->NumDisplayAdapters = 0;
D3D9_PrimaryDeviceName[0] = '\0';
AdapterIndex = 0;
while (EnumDisplayDevicesA(NULL, AdapterIndex, &DisplayDevice, 0) == TRUE &&
pDirect3D9->dwNumDisplayAdapters < DX_D3D9_MAX_NUM_ADAPTERS)
pDirect3D9->NumDisplayAdapters < DX_D3D9_MAX_NUM_ADAPTERS)
{
if ((DisplayDevice.StateFlags & (DISPLAY_DEVICE_DISCONNECT | DISPLAY_DEVICE_MIRRORING_DRIVER)) == 0 &&
(DisplayDevice.StateFlags & (DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) != 0)
{
SetAdapterInfo(&pDirect3D9->DisplayAdapters[pDirect3D9->dwNumDisplayAdapters], &DisplayDevice);
SetAdapterInfo(&pDirect3D9->DisplayAdapters[pDirect3D9->NumDisplayAdapters], &DisplayDevice);
if (pDirect3D9->dwNumDisplayAdapters == 0)
if (pDirect3D9->NumDisplayAdapters == 0)
lstrcpynA(D3D9_PrimaryDeviceName, DisplayDevice.DeviceName, sizeof(D3D9_PrimaryDeviceName));
++pDirect3D9->dwNumDisplayAdapters;
++pDirect3D9->NumDisplayAdapters;
break;
}
@ -79,27 +94,22 @@ static BOOL GetDisplayDeviceInfo(IN OUT LPDIRECT3D9_INT pDirect3D9)
AdapterIndex = 0;
while (EnumDisplayDevicesA(NULL, AdapterIndex, &DisplayDevice, 0) == TRUE &&
pDirect3D9->dwNumDisplayAdapters < DX_D3D9_MAX_NUM_ADAPTERS)
pDirect3D9->NumDisplayAdapters < DX_D3D9_MAX_NUM_ADAPTERS)
{
if ((DisplayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0 &&
(DisplayDevice.StateFlags & (DISPLAY_DEVICE_MIRRORING_DRIVER | DISPLAY_DEVICE_PRIMARY_DEVICE)) == 0)
{
SetAdapterInfo(&pDirect3D9->DisplayAdapters[pDirect3D9->dwNumDisplayAdapters], &DisplayDevice);
++pDirect3D9->dwNumDisplayAdapters;
SetAdapterInfo(&pDirect3D9->DisplayAdapters[pDirect3D9->NumDisplayAdapters], &DisplayDevice);
++pDirect3D9->NumDisplayAdapters;
}
++AdapterIndex;
}
/* Check if minimum DirectDraw is supported */
if (IsDirectDrawSupported() == FALSE)
return FALSE;
/* Test DC creation for primary display device */
if (NULL == (hDC = CreateDCA(NULL, D3D9_PrimaryDeviceName, NULL, NULL)))
return FALSE;
DeleteDC(hDC);
for (AdapterIndex = 0; AdapterIndex < pDirect3D9->NumDisplayAdapters; AdapterIndex++)
{
GetDirect3DAdapterInfo(&pDirect3D9->DisplayAdapters[AdapterIndex]);
}
return TRUE;
}

View file

@ -27,10 +27,10 @@ BOOL ReadRegistryValue(IN DWORD ValueType, IN LPCSTR ValueName, OUT LPBYTE DataB
DWORD Type;
LONG Ret;
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, D3D9_DebugRegPath, 0, KEY_QUERY_VALUE, &hKey))
if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, D3D9_DebugRegPath, 0, KEY_QUERY_VALUE, &hKey))
return FALSE;
Ret = RegQueryValueEx(hKey, ValueName, 0, &Type, DataBuffer, DataBufferSize);
Ret = RegQueryValueExA(hKey, ValueName, 0, &Type, DataBuffer, DataBufferSize);
RegCloseKey(hKey);

View file

@ -11,6 +11,9 @@
#include "d3d9_common.h"
#include "d3d9_private.h"
#define LOCK_D3D9() EnterCriticalSection(&This->d3d9_cs);
#define UNLOCK_D3D9() LeaveCriticalSection(&This->d3d9_cs);
/* Convert a IDirect3D9 pointer safely to the internal implementation struct */
LPDIRECT3D9_INT impl_from_IDirect3D9(LPDIRECT3D9 iface);

View file

@ -8,8 +8,9 @@
#include "d3d9_common.h"
#include <d3d9.h>
#include "d3d9_helpers.h"
#include <debug.h>
#include "d3d9_helpers.h"
#include "adapter.h"
/* IDirect3D9: IUnknown implementation */
static HRESULT WINAPI IDirect3D9Impl_QueryInterface(LPDIRECT3D9 iface, REFIID riid, LPVOID* ppvObject)
@ -59,17 +60,93 @@ static HRESULT WINAPI IDirect3D9Impl_RegisterSoftwareDevice(LPDIRECT3D9 iface, v
return D3D_OK;
}
/*++
* @name IDirect3D9::GetAdapterCount
* @implemented
*
* The function IDirect3D9Impl_GetAdapterCount returns the number of adapters
*
* @param LPDIRECT3D iface
* Pointer to the IDirect3D object returned from Direct3DCreate9()
*
* @return
* The number of display adapters on the system when Direct3DCreate9() was called.
*
*/
static UINT WINAPI IDirect3D9Impl_GetAdapterCount(LPDIRECT3D9 iface)
{
UNIMPLEMENTED
UINT NumDisplayAdapters;
return D3D_OK;
LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface);
LOCK_D3D9();
NumDisplayAdapters = This->NumDisplayAdapters;
UNLOCK_D3D9();
return NumDisplayAdapters;
}
static HRESULT WINAPI IDirect3D9Impl_GetAdapterIdentifier(LPDIRECT3D9 iface, UINT Adapter, DWORD Flags,
/*++
* @name IDirect3D9::GetAdapterIdentifier
* @implemented
*
* The function IDirect3D9Impl_GetAdapterIdentifier gathers information about
* a specified display adapter and fills the pIdentifier argument with the available information.
*
* @param LPDIRECT3D iface
* Pointer to the IDirect3D object returned from Direct3DCreate9()
*
* @param UINT Adapter
* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
* The maximum value for this is the value returned by IDirect3D::GetAdapterCount().
*
* @param DWORD Flags
* Ignored at the moment, but the only valid flag is D3DENUM_WHQL_LEVEL
*
* @param D3DADAPTER_IDENTIFIER9* pIdentifier
* Pointer to a D3DADAPTER_IDENTIFIER9 structure to be filled with the available information
* about the display adapter.
*
* @return
* If the method successfully fills the pIdentified structure, the return value is D3D_OK.
* If Adapter is out of range, Flags is invalid or pIdentifier is a bad pointer, the return value
* will be D3DERR_INVALIDCALL.
*
*/
HRESULT WINAPI IDirect3D9Impl_GetAdapterIdentifier(LPDIRECT3D9 iface, UINT Adapter, DWORD Flags,
D3DADAPTER_IDENTIFIER9* pIdentifier)
{
UNIMPLEMENTED
LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface);
LOCK_D3D9();
if (Adapter >= This->NumDisplayAdapters)
{
DPRINT1("Invalid Adapter number specified");
UNLOCK_D3D9();
return D3DERR_INVALIDCALL;
}
if (Flags & ~D3DENUM_WHQL_LEVEL)
{
DPRINT1("Invalid Flags specified");
UNLOCK_D3D9();
return D3DERR_INVALIDCALL;
}
if (IsBadWritePtr(pIdentifier, sizeof(D3DADAPTER_IDENTIFIER9)))
{
UNLOCK_D3D9();
return D3DERR_INVALIDCALL;
}
memset(pIdentifier, 0, sizeof(D3DADAPTER_IDENTIFIER9));
if (FALSE == GetAdapterInfo(This->DisplayAdapters[Adapter].szDeviceName, pIdentifier))
{
DPRINT1("Internal error: Couldn't get the adapter info for device (%d): %s", Adapter, This->DisplayAdapters[Adapter].szDeviceName);
UNLOCK_D3D9();
return D3DERR_INVALIDCALL;
}
return D3D_OK;
}
@ -150,7 +227,7 @@ static HMONITOR WINAPI IDirect3D9Impl_GetAdapterMonitor(LPDIRECT3D9 iface, UINT
{
UNIMPLEMENTED
return D3D_OK;
return NULL;
}
static HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType,
@ -163,7 +240,7 @@ static HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9 iface, UINT Adapte
return D3D_OK;
}
const IDirect3D9Vtbl Direct3D9_Vtbl =
IDirect3D9Vtbl Direct3D9_Vtbl =
{
/* IUnknown */
IDirect3D9Impl_QueryInterface,

View file

@ -26,7 +26,7 @@ typedef struct _tagDIRECT3D9DisplayAdapterInfo_
/* 0x0130 */ DWORD unknown000007;
/* 0x0134 */ DWORD unknown000008;
/* 0x0138 */ DWORD unknown000009;
/* 0x013c */ DWORD unknown000010;
/* 0x013c */ DWORD unknown000010; /* D3D9_DRIVERCAPS? */
/* 0x0140 */ DWORD unknown000011;
/* 0x0144 */ DWORD unknown000012;
/* 0x0148 */ DWORD unknown000013;
@ -126,13 +126,13 @@ typedef struct _tagDIRECT3D9DisplayAdapterInfo_
typedef struct _tagDIRECT3D9_INT_
{
/* 0x0000 */ const struct IDirect3D9Vtbl *lpVtbl; /* LPDIRECTD3D9 functoions table */
/* 0x0000 */ struct IDirect3D9Vtbl *lpVtbl; /* LPDIRECTD3D9 functoions table */
/* 0x0004 */ CRITICAL_SECTION d3d9_cs;
/* 0x001c */ DWORD unknown000007; /* 0x00000001 */
/* 0x0020 */ DWORD dwProcessId;
/* 0x0024 */ struct _tagDIRECT3D9_INT_ *lpInt;
/* 0x0028 */ LONG dwRefCnt; /* Increases and decreases by AddRef() and Release() */
/* 0x002c */ DWORD dwNumDisplayAdapters;
/* 0x002c */ UINT NumDisplayAdapters;
/* 0x0030 */ Direct3D9DisplayAdapterInfo_INT DisplayAdapters[DX_D3D9_MAX_NUM_ADAPTERS];
/* 0x2100 */ DWORD unknown002112;
/* 0x2104 */ DWORD unknown002113;
@ -2543,7 +2543,7 @@ typedef struct _tagDIRECT3D9_INT_
/* 0x4698 */ DWORD unknown004518;
/* 0x469c */ DWORD unknown004519;
/* 0x46a0 */ DWORD unknown004520;
/* 0x46a4 */ DWORD unknown004521;
/* 0x46a4 */ DWORD unknown004521; // Software only
/* 0x46a8 */ DWORD unknown004522;
/* 0x46ac */ DWORD unknown004523;
/* 0x46b0 */ DWORD unknown004524;