2 * PROJECT: ReactX Diagnosis Application
3 * LICENSE: LGPL - See COPYING in the top level directory
4 * FILE: base/applications/dxdiag/display.c
5 * PURPOSE: ReactX diagnosis display page
6 * COPYRIGHT: Copyright 2008 Johannes Anderwald
14 GetFileModifyTime(LPCWSTR pFullPath
, WCHAR
* szTime
, int szTimeSize
)
18 SYSTEMTIME SysTime
, LocalTime
;
20 TIME_ZONE_INFORMATION TimeInfo
;
22 hFile
= CreateFileW(pFullPath
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
26 if (!GetFileTime(hFile
, NULL
, NULL
, &AccessTime
))
33 if(!GetTimeZoneInformation(&TimeInfo
))
36 if (!FileTimeToSystemTime(&AccessTime
, &SysTime
))
39 if (!SystemTimeToTzSpecificLocalTime(&TimeInfo
, &SysTime
, &LocalTime
))
42 Length
= GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &LocalTime
, NULL
, szTime
, szTimeSize
);
43 szTime
[Length
-1] = L
' ';
44 return GetTimeFormatW(LOCALE_USER_DEFAULT
, TIME_FORCE24HOURFORMAT
, &LocalTime
, NULL
, &szTime
[Length
], szTimeSize
-Length
);
50 DriverFilesCallback(IN PVOID Context
,
57 LPCWSTR pFullPath
= (LPCWSTR
)Param1
;
59 LRESULT Length
, fLength
;
60 HWND
* hDlgCtrls
= (HWND
*)Context
;
62 if (wcsstr(pFullPath
, L
"\\DRIVERS\\"))
64 /* exclude files from drivers dir to have failsafe file version/date information */
68 pFile
= wcsrchr(pFullPath
, L
'\\');
73 fLength
= wcslen(pFile
) + 1;
75 Length
= SendMessageW(hDlgCtrls
[0], WM_GETTEXTLENGTH
, 0, 0) + 1;
76 pBuffer
= HeapAlloc(GetProcessHeap(), 0, (Length
+ fLength
) * sizeof(WCHAR
));
78 return ERROR_OUTOFMEMORY
;
80 Length
= SendMessageW(hDlgCtrls
[0], WM_GETTEXT
, Length
, (LPARAM
)pBuffer
);
83 pBuffer
[Length
++] = L
',';
87 /* set file version */
88 if (GetFileVersion(pFullPath
, szVer
, sizeof(szVer
)/sizeof(WCHAR
)))
89 SendMessageW(hDlgCtrls
[1], WM_SETTEXT
, 0, (LPARAM
)szVer
);
91 if (GetFileModifyTime(pFullPath
, szVer
, sizeof(szVer
)/sizeof(WCHAR
)))
92 SendMessageW(hDlgCtrls
[2], WM_SETTEXT
, 0, (LPARAM
)szVer
);
95 wcscpy(&pBuffer
[Length
], pFile
);
96 SendMessageW(hDlgCtrls
[0], WM_SETTEXT
, 0, (LPARAM
)pBuffer
);
97 HeapFree(GetProcessHeap(), 0, pBuffer
);
102 EnumerateDrivers(PVOID Context
, HDEVINFO hList
, PSP_DEVINFO_DATA pInfoData
)
105 SP_DEVINSTALL_PARAMS DeviceInstallParams
= {0};
106 SP_DRVINFO_DATA DriverInfoData
;
109 DeviceInstallParams
.cbSize
= sizeof(DeviceInstallParams
);
110 if (!SetupDiGetDeviceInstallParamsW(hList
, pInfoData
, &DeviceInstallParams
))
113 DeviceInstallParams
.FlagsEx
|= (DI_FLAGSEX_INSTALLEDDRIVER
| DI_FLAGSEX_ALLOWEXCLUDEDDRVS
);
114 if (!SetupDiSetDeviceInstallParams(hList
, pInfoData
, &DeviceInstallParams
))
117 if (!SetupDiBuildDriverInfoList(hList
, pInfoData
, SPDIT_CLASSDRIVER
))
120 DriverInfoData
.cbSize
= sizeof(DriverInfoData
);
121 if (!SetupDiEnumDriverInfoW(hList
, pInfoData
, SPDIT_CLASSDRIVER
, 0, &DriverInfoData
))
124 DriverInfoData
.cbSize
= sizeof(DriverInfoData
);
125 if (!SetupDiSetSelectedDriverW(hList
, pInfoData
, &DriverInfoData
))
128 hQueue
= SetupOpenFileQueue();
129 if (hQueue
== (HSPFILEQ
)INVALID_HANDLE_VALUE
)
132 DeviceInstallParams
.cbSize
= sizeof(DeviceInstallParams
);
133 if (!SetupDiGetDeviceInstallParamsW(hList
, pInfoData
, &DeviceInstallParams
))
135 SetupCloseFileQueue(hQueue
);
139 DeviceInstallParams
.FileQueue
= hQueue
;
140 DeviceInstallParams
.Flags
|= DI_NOVCP
;
142 if (!SetupDiSetDeviceInstallParamsW(hList
, pInfoData
, &DeviceInstallParams
))
144 SetupCloseFileQueue(hQueue
);
148 if(!SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES
, hList
, pInfoData
))
150 SetupCloseFileQueue(hQueue
);
155 /* enumerate the driver files */
156 SetupScanFileQueueW(hQueue
, SPQ_SCAN_USE_CALLBACK
, NULL
, DriverFilesCallback
, Context
, &Result
);
157 SetupCloseFileQueue(hQueue
);
162 SetDeviceDetails(HWND
* hDlgCtrls
, LPCGUID classGUID
, LPGUID
* deviceGUID
)
166 SP_DEVINFO_DATA InfoData
;
169 /* create the setup list */
170 hInfo
= SetupDiGetClassDevsW(classGUID
, NULL
, NULL
, DIGCF_PRESENT
|DIGCF_PROFILE
);
171 if (hInfo
== INVALID_HANDLE_VALUE
)
176 ZeroMemory(&InfoData
, sizeof(InfoData
));
177 InfoData
.cbSize
= sizeof(InfoData
);
179 if (SetupDiEnumDeviceInfo(hInfo
, dwIndex
, &InfoData
))
181 /* set device name */
182 if (SetupDiGetDeviceRegistryPropertyW(hInfo
, &InfoData
, SPDRP_DEVICEDESC
, NULL
, (PBYTE
)szText
, sizeof(szText
), NULL
))
183 SendMessageW(hDlgCtrls
[0], WM_SETTEXT
, 0, (LPARAM
)szText
);
185 /* set the manufacturer name */
186 if (SetupDiGetDeviceRegistryPropertyW(hInfo
, &InfoData
, SPDRP_MFG
, NULL
, (PBYTE
)szText
, sizeof(szText
), NULL
))
187 SendMessageW(hDlgCtrls
[1], WM_SETTEXT
, 0, (LPARAM
)szText
);
190 * we currently enumerate only the first adapter
192 EnumerateDrivers(&hDlgCtrls
[2], hInfo
, &InfoData
);
196 if (GetLastError() == ERROR_NO_MORE_ITEMS
)
202 /* destroy the setup list */
203 SetupDiDestroyDeviceInfoList(hInfo
);
209 InitializeDialog(HWND hwndDlg
, PDISPLAY_DEVICEW pDispDevice
)
218 D3DADAPTER_IDENTIFIER9 Identifier
;
222 ppObj
= Direct3DCreate9(D3D_SDK_VERSION
);
225 hResult
= IDirect3D9_GetAdapterIdentifier(ppObj
, D3DADAPTER_DEFAULT
, 2/*D3DENUM_WHQL_LEVEL*/, &Identifier
);
226 if (hResult
== D3D_OK
)
229 if (Identifier
.WHQLLevel
)
231 /* adapter is WHQL certified */
232 LoadStringW(hInst
, IDS_OPTION_YES
, szText
, sizeof(szText
)/sizeof(WCHAR
));
236 LoadStringW(hInst
, IDS_OPTION_NO
, szText
, sizeof(szText
)/sizeof(WCHAR
));
239 IDirect3D9_Release(ppObj
);
243 LoadStringW(hInst
, IDS_DEVICE_STATUS_UNKNOWN
, szText
, sizeof(szText
)/sizeof(WCHAR
));
245 szText
[(sizeof(szText
)/sizeof(WCHAR
))-1] = L
'\0';
246 SendDlgItemMessageW(hwndDlg
, IDC_STATIC_ADAPTER_LOGO
, WM_SETTEXT
, 0, (LPARAM
)szText
);
248 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, &pDispDevice
->DeviceKey
[18], 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
251 if (GetRegValue(hKey
, NULL
, L
"HardwareInformation.ChipType", REG_BINARY
, szText
, sizeof(szText
)))
254 SendDlgItemMessageW(hwndDlg
, IDC_STATIC_ADAPTER_CHIP
, WM_SETTEXT
, 0, (LPARAM
)szText
);
257 if (GetRegValue(hKey
, NULL
, L
"HardwareInformation.DacType", REG_BINARY
, szText
, sizeof(szText
)))
260 SendDlgItemMessageW(hwndDlg
, IDC_STATIC_ADAPTER_DAC
, WM_SETTEXT
, 0, (LPARAM
)szText
);
263 if (GetRegValue(hKey
, NULL
, L
"HardwareInformation.MemorySize", REG_BINARY
, (LPWSTR
)&dwMemory
, sizeof(dwMemory
)))
265 /* set chip memory size */
266 if (dwMemory
> (1048576))
268 /* buggy ATI driver requires that */
272 if (LoadStringW(hInst
, IDS_FORMAT_ADAPTER_MEM
, szFormat
, sizeof(szFormat
)/sizeof(WCHAR
)))
273 szFormat
[(sizeof(szFormat
)/sizeof(WCHAR
))-1] = L
'\0';
274 wsprintfW(szText
, szFormat
, dwMemory
);
275 SendDlgItemMessageW(hwndDlg
, IDC_STATIC_ADAPTER_MEM
, WM_SETTEXT
, 0, (LPARAM
)szText
);
278 /* retrieve current display mode */
279 DevMode
.dmSize
= sizeof(DEVMODE
);
280 if (EnumDisplaySettingsW(pDispDevice
->DeviceName
, ENUM_CURRENT_SETTINGS
, &DevMode
))
283 if (LoadStringW(hInst
, IDS_FORMAT_ADAPTER_MODE
, szFormat
, sizeof(szFormat
)/sizeof(WCHAR
)))
284 szFormat
[(sizeof(szFormat
)/sizeof(WCHAR
))-1] = L
'\0';
285 wsprintfW(szText
, szFormat
, DevMode
.dmPelsWidth
, DevMode
.dmPelsHeight
, DevMode
.dmBitsPerPel
, DevMode
.dmDisplayFrequency
);
286 SendDlgItemMessageW(hwndDlg
, IDC_STATIC_ADAPTER_MODE
, WM_SETTEXT
, 0, (LPARAM
)szText
);
289 /* query attached monitor */
290 wcscpy(szText
, pDispDevice
->DeviceName
);
291 ZeroMemory(pDispDevice
, sizeof(DISPLAY_DEVICEW
));
292 pDispDevice
->cb
= sizeof(DISPLAY_DEVICEW
);
293 if (EnumDisplayDevicesW(szText
, 0, pDispDevice
, 0))
295 /* set monitor name */
296 SendDlgItemMessageW(hwndDlg
, IDC_STATIC_ADAPTER_MONITOR
, WM_SETTEXT
, 0, (LPARAM
)pDispDevice
->DeviceString
);
299 hDlgCtrls
[0] = GetDlgItem(hwndDlg
, IDC_STATIC_ADAPTER_ID
);
300 hDlgCtrls
[1] = GetDlgItem(hwndDlg
, IDC_STATIC_ADAPTER_VENDOR
);
301 hDlgCtrls
[2] = GetDlgItem(hwndDlg
, IDC_STATIC_ADAPTER_DRIVER
);
302 hDlgCtrls
[3] = GetDlgItem(hwndDlg
, IDC_STATIC_ADAPTER_VERSION
);
303 hDlgCtrls
[4] = GetDlgItem(hwndDlg
, IDC_STATIC_ADAPTER_DATE
);
305 SetDeviceDetails(hDlgCtrls
, &GUID_DEVCLASS_DISPLAY
, NULL
);
309 void InitializeDisplayAdapters(PDXDIAG_CONTEXT pContext
)
311 DISPLAY_DEVICEW DispDevice
;
320 ZeroMemory(&DispDevice
, sizeof(DISPLAY_DEVICEW
));
321 DispDevice
.cb
= sizeof(DISPLAY_DEVICEW
);
322 if (!EnumDisplayDevicesW(NULL
, pContext
->NumDisplayAdapter
+ dwOffset
, &DispDevice
, 0))
325 /* skip devices not attached to the desktop and mirror drivers */
326 if (!(DispDevice
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
) || (DispDevice
.StateFlags
& DISPLAY_DEVICE_MIRRORING_DRIVER
))
331 if (pContext
->NumDisplayAdapter
)
332 hDlgs
= HeapReAlloc(GetProcessHeap(), 0, pContext
->hDisplayWnd
, (pContext
->NumDisplayAdapter
+ 1) * sizeof(HWND
));
334 hDlgs
= HeapAlloc(GetProcessHeap(), 0, (pContext
->NumDisplayAdapter
+ 1) * sizeof(HWND
));
339 pContext
->hDisplayWnd
= hDlgs
;
340 hwndDlg
= CreateDialogParamW(hInst
, MAKEINTRESOURCEW(IDD_DISPLAY_DIALOG
), pContext
->hMainDialog
, DisplayPageWndProc
, (LPARAM
)pContext
);
344 /* initialize the dialog */
345 InitializeDialog(hwndDlg
, &DispDevice
);
347 szDisplay
[0] = L
'\0';
348 LoadStringW(hInst
, IDS_DISPLAY_DIALOG
, szDisplay
, sizeof(szDisplay
)/sizeof(WCHAR
));
349 szDisplay
[(sizeof(szDisplay
)/sizeof(WCHAR
))-1] = L
'\0';
351 wsprintfW (szText
, L
"%s %u", szDisplay
, pContext
->NumDisplayAdapter
+ 1);
352 InsertTabCtrlItem(GetDlgItem(pContext
->hMainDialog
, IDC_TAB_CONTROL
), pContext
->NumDisplayAdapter
+ 1, szText
);
354 hDlgs
[pContext
->NumDisplayAdapter
] = hwndDlg
;
355 pContext
->NumDisplayAdapter
++;
363 DisplayPageWndProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
366 PDXDIAG_CONTEXT pContext
= (PDXDIAG_CONTEXT
)GetWindowLongPtr(hDlg
, DWLP_USER
);
371 pContext
= (PDXDIAG_CONTEXT
) lParam
;
372 SetWindowLongPtr(hDlg
, DWLP_USER
, (LONG_PTR
)pContext
);
373 SetWindowPos(hDlg
, NULL
, 10, 32, 0, 0, SWP_NOACTIVATE
| SWP_NOOWNERZORDER
| SWP_NOSIZE
| SWP_NOZORDER
);
378 switch(LOWORD(wParam
))
380 case IDC_BUTTON_TESTDD
:
381 case IDC_BUTTON_TEST3D
:
382 GetWindowRect(pContext
->hMainDialog
, &rect
);
383 /* FIXME log result errors */
384 if (IDC_BUTTON_TESTDD
== LOWORD(wParam
))
386 else if (IDC_BUTTON_TEST3D
== LOWORD(wParam
))
388 SetWindowPos(pContext
->hMainDialog
, NULL
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
, SWP_NOACTIVATE
| SWP_NOOWNERZORDER
| SWP_NOSIZE
| SWP_NOZORDER
);