Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

261 lines
8.7 KiB

  1. /****************************************************************************
  2. *
  3. * File: dispinfo8.cpp
  4. * Project: DxDiag (DirectX Diagnostic Tool)
  5. * Author: Jason Sandlin (jasonsa@microsoft.com)
  6. * Purpose: Gather D3D8 information
  7. *
  8. * (C) Copyright 2000 Microsoft Corp. All rights reserved.
  9. *
  10. ****************************************************************************/
  11. #include <tchar.h>
  12. #include <Windows.h>
  13. #define DIRECT3D_VERSION 0x0800 // file uses DX8
  14. #include <d3d8.h>
  15. #include <stdio.h>
  16. #include "sysinfo.h"
  17. #include "reginfo.h"
  18. #include "dispinfo.h"
  19. typedef IDirect3D8* (WINAPI* LPDIRECT3DCREATE8)(UINT SDKVersion);
  20. static BOOL IsMatchWithDisplayDevice( DisplayInfo* pDisplayInfo, HMONITOR hMonitor, BOOL bCanRenderWindow );
  21. static HINSTANCE s_hInstD3D8 = NULL;
  22. static IDirect3D8* s_pD3D8 = NULL;
  23. static BOOL s_bD3D8WrongHeaders = FALSE;
  24. /****************************************************************************
  25. *
  26. * InitD3D8
  27. *
  28. ****************************************************************************/
  29. HRESULT InitD3D8()
  30. {
  31. LPDIRECT3DCREATE8 pD3DCreate8 = NULL;
  32. TCHAR szPath[MAX_PATH];
  33. GetSystemDirectory(szPath, MAX_PATH);
  34. lstrcat(szPath, TEXT("\\d3d8.dll"));
  35. // This may fail if DX8 isn't on the system
  36. s_hInstD3D8 = LoadLibrary(szPath);
  37. if (s_hInstD3D8 == NULL)
  38. return E_FAIL;
  39. pD3DCreate8 = (LPDIRECT3DCREATE8)GetProcAddress(s_hInstD3D8, "Direct3DCreate8");
  40. if (pD3DCreate8 == NULL)
  41. {
  42. FreeLibrary(s_hInstD3D8);
  43. s_hInstD3D8 = NULL;
  44. return E_FAIL;
  45. }
  46. s_pD3D8 = pD3DCreate8(D3D_SDK_VERSION);
  47. if( s_pD3D8 == NULL )
  48. {
  49. // We have the wrong headers since d3d8.dll loaded but D3DCreate8() failed.
  50. s_bD3D8WrongHeaders = TRUE;
  51. }
  52. return S_OK;
  53. }
  54. /****************************************************************************
  55. *
  56. * CleanupD3D8
  57. *
  58. ****************************************************************************/
  59. VOID CleanupD3D8()
  60. {
  61. if( s_pD3D8 )
  62. {
  63. s_pD3D8->Release();
  64. s_pD3D8 = NULL;
  65. }
  66. if( s_hInstD3D8 )
  67. {
  68. FreeLibrary(s_hInstD3D8);
  69. s_hInstD3D8 = NULL;
  70. }
  71. }
  72. /****************************************************************************
  73. *
  74. * IsD3D8Working
  75. *
  76. ****************************************************************************/
  77. BOOL IsD3D8Working()
  78. {
  79. if( s_pD3D8 )
  80. return TRUE;
  81. else
  82. return FALSE;
  83. }
  84. /****************************************************************************
  85. *
  86. * GetDX8AdapterInfo
  87. *
  88. ****************************************************************************/
  89. HRESULT GetDX8AdapterInfo(DisplayInfo* pDisplayInfo)
  90. {
  91. UINT nAdapterCount;
  92. D3DADAPTER_IDENTIFIER8 d3d8Id;
  93. D3DCAPS8 d3d8Caps;
  94. UINT iAdapter;
  95. HMONITOR hMonitor;
  96. BOOL bCanRenderWindow;
  97. BOOL bIsDDI8;
  98. // D3D8 may not exist on this system
  99. if( s_pD3D8 == NULL )
  100. {
  101. _tcscpy( pDisplayInfo->m_szDX8DriverSignDate, TEXT("n/a") );
  102. _tcscpy( pDisplayInfo->m_szDX8VendorId, TEXT("n/a") );
  103. _tcscpy( pDisplayInfo->m_szDX8DeviceId, TEXT("n/a") );
  104. _tcscpy( pDisplayInfo->m_szDX8SubSysId, TEXT("n/a") );
  105. _tcscpy( pDisplayInfo->m_szDX8Revision, TEXT("n/a") );
  106. if( s_bD3D8WrongHeaders )
  107. {
  108. _tcscpy( pDisplayInfo->m_szDX8DeviceIdentifier,
  109. TEXT("Could not initialize Direct3D v8. ")
  110. TEXT("This program was compiled with header ")
  111. TEXT("files that do not match the installed ")
  112. TEXT("DirectX DLLs") );
  113. }
  114. else
  115. {
  116. _tcscpy( pDisplayInfo->m_szDX8DeviceIdentifier, TEXT("n/a") );
  117. }
  118. return S_OK;
  119. }
  120. // Get the # of adapters on the system
  121. nAdapterCount = s_pD3D8->GetAdapterCount();
  122. // For each adapter try to match it to the pDisplayInfo using the HMONTIOR
  123. for( iAdapter=0; iAdapter<nAdapterCount; iAdapter++ )
  124. {
  125. bCanRenderWindow = TRUE;
  126. bIsDDI8 = FALSE;
  127. // Get the HMONITOR for this adapter
  128. hMonitor = s_pD3D8->GetAdapterMonitor( iAdapter );
  129. // Get the caps for this adapter
  130. ZeroMemory( &d3d8Caps, sizeof(D3DCAPS8) );
  131. if( SUCCEEDED( s_pD3D8->GetDeviceCaps( iAdapter, D3DDEVTYPE_HAL, &d3d8Caps ) ) )
  132. {
  133. // Record if its a non-GDI (Voodoo1/2) card
  134. bCanRenderWindow = ( (d3d8Caps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) != 0 );
  135. // Check if its a DDI v8 driver
  136. bIsDDI8 = ( d3d8Caps.MaxStreams > 0 );
  137. }
  138. // Check to see if the pDisplayInfo matchs with this adapter,
  139. // and if not, then keep looking
  140. if( !IsMatchWithDisplayDevice( pDisplayInfo, hMonitor, bCanRenderWindow ) )
  141. continue;
  142. // Record the DDI version if the caps told us
  143. if( bIsDDI8 )
  144. pDisplayInfo->m_dwDDIVersion = 8;
  145. // Link this iAdapter to this pDisplayInfo
  146. pDisplayInfo->m_iAdapter = iAdapter;
  147. // Get the D3DADAPTER_IDENTIFIER8 for this adapter
  148. ZeroMemory( &d3d8Id, sizeof(D3DADAPTER_IDENTIFIER8) );
  149. if( SUCCEEDED( s_pD3D8->GetAdapterIdentifier( iAdapter, 0, &d3d8Id ) ) )
  150. {
  151. // Copy various IDs
  152. wsprintf( pDisplayInfo->m_szDX8VendorId, TEXT("0x%04.4X"), d3d8Id.VendorId );
  153. wsprintf( pDisplayInfo->m_szDX8DeviceId, TEXT("0x%04.4X"), d3d8Id.DeviceId );
  154. wsprintf( pDisplayInfo->m_szDX8SubSysId, TEXT("0x%08.8X"), d3d8Id.SubSysId );
  155. wsprintf( pDisplayInfo->m_szDX8Revision, TEXT("0x%04.4X"), d3d8Id.Revision );
  156. // Copy device GUID
  157. pDisplayInfo->m_guidDX8DeviceIdentifier = d3d8Id.DeviceIdentifier;
  158. _stprintf( pDisplayInfo->m_szDX8DeviceIdentifier, TEXT("{%08.8X-%04.4X-%04.4X-%02.2X%02.2X-%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X}"),
  159. d3d8Id.DeviceIdentifier.Data1, d3d8Id.DeviceIdentifier.Data2, d3d8Id.DeviceIdentifier.Data3,
  160. d3d8Id.DeviceIdentifier.Data4[0], d3d8Id.DeviceIdentifier.Data4[1],
  161. d3d8Id.DeviceIdentifier.Data4[2], d3d8Id.DeviceIdentifier.Data4[3],
  162. d3d8Id.DeviceIdentifier.Data4[4], d3d8Id.DeviceIdentifier.Data4[5],
  163. d3d8Id.DeviceIdentifier.Data4[6], d3d8Id.DeviceIdentifier.Data4[7] );
  164. // Copy and parse the WHQLLevel
  165. // 0 == Not signed.
  166. // 1 == WHQL signed, but no date information is available.
  167. // >1 means signed, date bit packed
  168. pDisplayInfo->m_dwDX8WHQLLevel = d3d8Id.WHQLLevel;
  169. if( d3d8Id.WHQLLevel == 0 )
  170. {
  171. pDisplayInfo->m_bDX8DriverSigned = FALSE;
  172. pDisplayInfo->m_bDX8DriverSignedValid = TRUE;
  173. }
  174. else
  175. {
  176. pDisplayInfo->m_bDX8DriverSigned = TRUE;
  177. pDisplayInfo->m_bDX8DriverSignedValid = TRUE;
  178. pDisplayInfo->m_bDriverSigned = TRUE;
  179. pDisplayInfo->m_bDriverSignedValid = TRUE;
  180. if( d3d8Id.WHQLLevel == 1 )
  181. {
  182. lstrcpy( pDisplayInfo->m_szDX8DriverSignDate, TEXT("n/a") );
  183. }
  184. else
  185. {
  186. // Bits encoded as:
  187. // 31-16: The year, a decimal number from 1999 upwards.
  188. // 15-8: The month, a decimal number from 1 to 12.
  189. // 7-0: The day, a decimal number from 1 to 31.
  190. DWORD dwMonth, dwDay, dwYear;
  191. dwYear = (d3d8Id.WHQLLevel >> 16);
  192. dwMonth = (d3d8Id.WHQLLevel >> 8) & 0x000F;
  193. dwDay = (d3d8Id.WHQLLevel >> 0) & 0x000F;
  194. wsprintf( pDisplayInfo->m_szDX8DriverSignDate,
  195. TEXT("%d/%d/%d"), dwMonth, dwDay, dwYear );
  196. }
  197. }
  198. }
  199. return S_OK;
  200. }
  201. // Hmm. This shouldn't happen since we should have found a match...
  202. return E_FAIL;
  203. }
  204. /****************************************************************************
  205. *
  206. * IsMatchWithDisplayDevice
  207. *
  208. ****************************************************************************/
  209. BOOL IsMatchWithDisplayDevice( DisplayInfo* pDisplayInfo, HMONITOR hMonitor,
  210. BOOL bCanRenderWindow )
  211. {
  212. // If the HMONITORs and the bCanRenderWindow match, then its good
  213. if( pDisplayInfo->m_hMonitor == hMonitor &&
  214. pDisplayInfo->m_bCanRenderWindow == bCanRenderWindow )
  215. return TRUE;
  216. else
  217. return FALSE;
  218. }