Author: gbrunmar Date: Tue Feb 5 00:33:12 2008 New Revision: 32122
URL: http://svn.reactos.org/svn/reactos?rev=32122&view=rev Log: * Implemented IDirect3D9's GetAdapterCount() and GetAdapterIdentifier() * Made d3d9.dll compile with MSVC
Added: trunk/reactos/dll/directx/d3d9/adapter.c (with props) trunk/reactos/dll/directx/d3d9/adapter.h (with props) Modified: trunk/reactos/dll/directx/d3d9/d3d9.rbuild trunk/reactos/dll/directx/d3d9/d3d9_common.h trunk/reactos/dll/directx/d3d9/d3d9_create.c trunk/reactos/dll/directx/d3d9/d3d9_helpers.c trunk/reactos/dll/directx/d3d9/d3d9_helpers.h trunk/reactos/dll/directx/d3d9/d3d9_impl.c trunk/reactos/dll/directx/d3d9/d3d9_private.h
Added: trunk/reactos/dll/directx/d3d9/adapter.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/d3d9/adapter.c?... ============================================================================== --- trunk/reactos/dll/directx/d3d9/adapter.c (added) +++ trunk/reactos/dll/directx/d3d9/adapter.c Tue Feb 5 00:33:12 2008 @@ -1,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; +}
Propchange: trunk/reactos/dll/directx/d3d9/adapter.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/dll/directx/d3d9/adapter.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/d3d9/adapter.h?... ============================================================================== --- trunk/reactos/dll/directx/d3d9/adapter.h (added) +++ trunk/reactos/dll/directx/d3d9/adapter.h Tue Feb 5 00:33:12 2008 @@ -1,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
Propchange: trunk/reactos/dll/directx/d3d9/adapter.h ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/dll/directx/d3d9/d3d9.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/d3d9/d3d9.rbuil... ============================================================================== --- trunk/reactos/dll/directx/d3d9/d3d9.rbuild (original) +++ trunk/reactos/dll/directx/d3d9/d3d9.rbuild Tue Feb 5 00:33:12 2008 @@ -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>
Modified: trunk/reactos/dll/directx/d3d9/d3d9_common.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/d3d9/d3d9_commo... ============================================================================== --- trunk/reactos/dll/directx/d3d9/d3d9_common.h (original) +++ trunk/reactos/dll/directx/d3d9/d3d9_common.h Tue Feb 5 00:33:12 2008 @@ -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_
Modified: trunk/reactos/dll/directx/d3d9/d3d9_create.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/d3d9/d3d9_creat... ============================================================================== --- trunk/reactos/dll/directx/d3d9/d3d9_create.c (original) +++ trunk/reactos/dll/directx/d3d9/d3d9_create.c Tue Feb 5 00:33:12 2008 @@ -46,31 +46,46 @@ 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 @@
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; }
Modified: trunk/reactos/dll/directx/d3d9/d3d9_helpers.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/d3d9/d3d9_helpe... ============================================================================== --- trunk/reactos/dll/directx/d3d9/d3d9_helpers.c (original) +++ trunk/reactos/dll/directx/d3d9/d3d9_helpers.c Tue Feb 5 00:33:12 2008 @@ -27,10 +27,10 @@ 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);
Modified: trunk/reactos/dll/directx/d3d9/d3d9_helpers.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/d3d9/d3d9_helpe... ============================================================================== --- trunk/reactos/dll/directx/d3d9/d3d9_helpers.h (original) +++ trunk/reactos/dll/directx/d3d9/d3d9_helpers.h Tue Feb 5 00:33:12 2008 @@ -10,6 +10,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);
Modified: trunk/reactos/dll/directx/d3d9/d3d9_impl.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/d3d9/d3d9_impl.... ============================================================================== --- trunk/reactos/dll/directx/d3d9/d3d9_impl.c (original) +++ trunk/reactos/dll/directx/d3d9/d3d9_impl.c Tue Feb 5 00:33:12 2008 @@ -8,8 +8,9 @@
#include "d3d9_common.h" #include <d3d9.h> +#include <debug.h> #include "d3d9_helpers.h" -#include <debug.h> +#include "adapter.h"
/* IDirect3D9: IUnknown implementation */ static HRESULT WINAPI IDirect3D9Impl_QueryInterface(LPDIRECT3D9 iface, REFIID riid, LPVOID* ppvObject) @@ -59,17 +60,93 @@ 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 - - return D3D_OK; -} - -static HRESULT WINAPI IDirect3D9Impl_GetAdapterIdentifier(LPDIRECT3D9 iface, UINT Adapter, DWORD Flags, + UINT NumDisplayAdapters; + + LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface); + LOCK_D3D9(); + + NumDisplayAdapters = This->NumDisplayAdapters; + + UNLOCK_D3D9(); + return NumDisplayAdapters; +} + +/*++ +* @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 @@ { UNIMPLEMENTED
- return D3D_OK; + return NULL; }
static HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, @@ -163,7 +240,7 @@ return D3D_OK; }
-const IDirect3D9Vtbl Direct3D9_Vtbl = +IDirect3D9Vtbl Direct3D9_Vtbl = { /* IUnknown */ IDirect3D9Impl_QueryInterface,
Modified: trunk/reactos/dll/directx/d3d9/d3d9_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/d3d9/d3d9_priva... ============================================================================== --- trunk/reactos/dll/directx/d3d9/d3d9_private.h (original) +++ trunk/reactos/dll/directx/d3d9/d3d9_private.h Tue Feb 5 00:33:12 2008 @@ -26,7 +26,7 @@ /* 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 _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 @@ /* 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;