modified dll/win32/kernel32/kernel32.rbuild
[reactos.git] / reactos / base / applications / dxdiag / display.c
1 /*
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
7 *
8 */
9
10 #include "precomp.h"
11 #include <initguid.h>
12 #include <devguid.h>
13
14 BOOL
15 GetFileModifyTime(LPCWSTR pFullPath, WCHAR * szTime, int szTimeSize)
16 {
17 HANDLE hFile;
18 FILETIME AccessTime;
19 SYSTEMTIME SysTime, LocalTime;
20 UINT Length;
21 TIME_ZONE_INFORMATION TimeInfo;
22
23 hFile = CreateFileW(pFullPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
24 if (!hFile)
25 return FALSE;
26
27 if (!GetFileTime(hFile, NULL, NULL, &AccessTime))
28 {
29 CloseHandle(hFile);
30 return FALSE;
31 }
32 CloseHandle(hFile);
33
34 if(!GetTimeZoneInformation(&TimeInfo))
35 return FALSE;
36
37 if (!FileTimeToSystemTime(&AccessTime, &SysTime))
38 return FALSE;
39
40 if (!SystemTimeToTzSpecificLocalTime(&TimeInfo, &SysTime, &LocalTime))
41 return FALSE;
42
43 Length = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &LocalTime, NULL, szTime, szTimeSize);
44 szTime[Length-1] = L' ';
45 return GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_FORCE24HOURFORMAT, &LocalTime, NULL, &szTime[Length], szTimeSize-Length);
46 }
47
48
49
50 static UINT WINAPI
51 DriverFilesCallback(IN PVOID Context,
52 IN UINT Notification,
53 IN UINT_PTR Param1,
54 IN UINT_PTR Param2)
55 {
56 LPCWSTR pFile;
57 LPWSTR pBuffer;
58 LPCWSTR pFullPath = (LPCWSTR)Param1;
59 WCHAR szVer[60];
60 LRESULT Length, fLength;
61 HWND * hDlgCtrls = (HWND *)Context;
62
63 if (wcsstr(pFullPath, L"\\DRIVERS\\"))
64 {
65 /* exclude files from drivers dir to have failsafe file version/date information */
66 return NO_ERROR;
67 }
68
69 pFile = wcsrchr(pFullPath, L'\\');
70 if (!pFile)
71 return NO_ERROR;
72
73 pFile++;
74 fLength = wcslen(pFile) + 1;
75
76 Length = SendMessageW(hDlgCtrls[0], WM_GETTEXTLENGTH, 0, 0) + 1;
77 pBuffer = HeapAlloc(GetProcessHeap(), 0, (Length + fLength) * sizeof(WCHAR));
78 if (!pBuffer)
79 return ERROR_OUTOFMEMORY;
80
81 Length = SendMessageW(hDlgCtrls[0], WM_GETTEXT, Length, (LPARAM)pBuffer);
82 if (Length)
83 {
84 pBuffer[Length++] = L',';
85 }
86 else
87 {
88 /* set file version */
89 if (GetFileVersion(pFullPath, szVer, sizeof(szVer)/sizeof(WCHAR)))
90 SendMessageW(hDlgCtrls[1], WM_SETTEXT, 0, (LPARAM)szVer);
91 /* set file time */
92 if (GetFileModifyTime(pFullPath, szVer, sizeof(szVer)/sizeof(WCHAR)))
93 SendMessageW(hDlgCtrls[2], WM_SETTEXT, 0, (LPARAM)szVer);
94 }
95
96 wcscpy(&pBuffer[Length], pFile);
97 SendMessageW(hDlgCtrls[0], WM_SETTEXT, 0, (LPARAM)pBuffer);
98 HeapFree(GetProcessHeap(), 0, pBuffer);
99 return NO_ERROR;
100 }
101
102 VOID
103 EnumerateDrivers(PVOID Context, HDEVINFO hList, PSP_DEVINFO_DATA pInfoData)
104 {
105 HSPFILEQ hQueue;
106 SP_DEVINSTALL_PARAMS DeviceInstallParams = {0};
107 SP_DRVINFO_DATA DriverInfoData;
108 DWORD Result;
109
110 DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
111 if (!SetupDiGetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams))
112 return;
113
114 DeviceInstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS);
115 if (!SetupDiSetDeviceInstallParams(hList, pInfoData, &DeviceInstallParams))
116 return;
117
118 if (!SetupDiBuildDriverInfoList(hList, pInfoData, SPDIT_CLASSDRIVER))
119 return;
120
121 DriverInfoData.cbSize = sizeof(DriverInfoData);
122 if (!SetupDiEnumDriverInfoW(hList, pInfoData, SPDIT_CLASSDRIVER, 0, &DriverInfoData))
123 return;
124
125 DriverInfoData.cbSize = sizeof(DriverInfoData);
126 if (!SetupDiSetSelectedDriverW(hList, pInfoData, &DriverInfoData))
127 return;
128
129 hQueue = SetupOpenFileQueue();
130 if (hQueue == (HSPFILEQ)INVALID_HANDLE_VALUE)
131 return;
132
133 DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
134 if (!SetupDiGetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams))
135 {
136 SetupCloseFileQueue(hQueue);
137 return;
138 }
139
140 DeviceInstallParams.FileQueue = hQueue;
141 DeviceInstallParams.Flags |= DI_NOVCP;
142
143 if (!SetupDiSetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams))
144 {
145 SetupCloseFileQueue(hQueue);
146 return;
147 }
148
149 if(!SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hList, pInfoData))
150 {
151 SetupCloseFileQueue(hQueue);
152 return;
153 }
154
155
156 /* enumerate the driver files */
157 SetupScanFileQueueW(hQueue, SPQ_SCAN_USE_CALLBACK, NULL, DriverFilesCallback, Context, &Result);
158 SetupCloseFileQueue(hQueue);
159 }
160
161 static
162 void
163 SetDeviceDetails(HWND * hDlgCtrls, LPCGUID classGUID, LPGUID * deviceGUID)
164 {
165 HDEVINFO hInfo;
166 DWORD dwIndex = 0;
167 SP_DEVINFO_DATA InfoData;
168 WCHAR szText[100];
169
170 /* create the setup list */
171 hInfo = SetupDiGetClassDevsW(classGUID, NULL, NULL, DIGCF_PRESENT|DIGCF_PROFILE);
172 if (hInfo == INVALID_HANDLE_VALUE)
173 return;
174
175 do
176 {
177 ZeroMemory(&InfoData, sizeof(InfoData));
178 InfoData.cbSize = sizeof(InfoData);
179
180 if (SetupDiEnumDeviceInfo(hInfo, dwIndex, &InfoData))
181 {
182 /* set device name */
183 if (SetupDiGetDeviceRegistryPropertyW(hInfo, &InfoData, SPDRP_DEVICEDESC, NULL, (PBYTE)szText, sizeof(szText), NULL))
184 SendMessageW(hDlgCtrls[0], WM_SETTEXT, 0, (LPARAM)szText);
185
186 /* set the manufacturer name */
187 if (SetupDiGetDeviceRegistryPropertyW(hInfo, &InfoData, SPDRP_MFG, NULL, (PBYTE)szText, sizeof(szText), NULL))
188 SendMessageW(hDlgCtrls[1], WM_SETTEXT, 0, (LPARAM)szText);
189
190 /* FIXME
191 * we currently enumerate only the first adapter
192 */
193 EnumerateDrivers(&hDlgCtrls[2], hInfo, &InfoData);
194 break;
195 }
196
197 if (GetLastError() == ERROR_NO_MORE_ITEMS)
198 break;
199
200 dwIndex++;
201 }while(TRUE);
202
203 /* destroy the setup list */
204 SetupDiDestroyDeviceInfoList(hInfo);
205 }
206
207
208 static
209 BOOL
210 InitializeDialog(HWND hwndDlg, PDISPLAY_DEVICEW pDispDevice)
211 {
212 WCHAR szText[100];
213 WCHAR szFormat[30];
214 HKEY hKey;
215 HWND hDlgCtrls[5];
216 DWORD dwMemory;
217 DEVMODE DevMode;
218 IDirect3D9 * ppObj;
219 D3DADAPTER_IDENTIFIER9 Identifier;
220 HRESULT hResult;
221
222 szText[0] = L'\0';
223 ppObj = Direct3DCreate9(D3D_SDK_VERSION);
224 if (ppObj)
225 {
226 hResult = IDirect3D9_GetAdapterIdentifier(ppObj, D3DADAPTER_DEFAULT , 2/*D3DENUM_WHQL_LEVEL*/, &Identifier);
227 if (hResult == D3D_OK)
228 {
229
230 if (Identifier.WHQLLevel)
231 {
232 /* adapter is WHQL certified */
233 LoadStringW(hInst, IDS_OPTION_YES, szText, sizeof(szText)/sizeof(WCHAR));
234 }
235 else
236 {
237 LoadStringW(hInst, IDS_OPTION_NO, szText, sizeof(szText)/sizeof(WCHAR));
238 }
239 }
240 IDirect3D9_Release(ppObj);
241 }
242 else
243 {
244 LoadStringW(hInst, IDS_DEVICE_STATUS_UNKNOWN, szText, sizeof(szText)/sizeof(WCHAR));
245 }
246 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
247 SendDlgItemMessageW(hwndDlg, IDC_STATIC_ADAPTER_LOGO, WM_SETTEXT, 0, (LPARAM)szText);
248
249 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, &pDispDevice->DeviceKey[18], 0, KEY_READ, &hKey) != ERROR_SUCCESS)
250 return FALSE;
251
252 if (GetRegValue(hKey, NULL, L"HardwareInformation.ChipType", REG_BINARY, szText, sizeof(szText)))
253 {
254 /* set chip type */
255 SendDlgItemMessageW(hwndDlg, IDC_STATIC_ADAPTER_CHIP, WM_SETTEXT, 0, (LPARAM)szText);
256 }
257
258 if (GetRegValue(hKey, NULL, L"HardwareInformation.DacType", REG_BINARY, szText, sizeof(szText)))
259 {
260 /* set DAC type */
261 SendDlgItemMessageW(hwndDlg, IDC_STATIC_ADAPTER_DAC, WM_SETTEXT, 0, (LPARAM)szText);
262 }
263
264 if (GetRegValue(hKey, NULL, L"HardwareInformation.MemorySize", REG_BINARY, (LPWSTR)&dwMemory, sizeof(dwMemory)))
265 {
266 /* set chip memory size */
267 if (dwMemory > (1048576))
268 {
269 /* buggy ATI driver requires that */
270 dwMemory /= 1048576;
271 }
272 szFormat[0] = L'\0';
273 if (LoadStringW(hInst, IDS_FORMAT_ADAPTER_MEM, szFormat, sizeof(szFormat)/sizeof(WCHAR)))
274 szFormat[(sizeof(szFormat)/sizeof(WCHAR))-1] = L'\0';
275 wsprintfW(szText, szFormat, dwMemory);
276 SendDlgItemMessageW(hwndDlg, IDC_STATIC_ADAPTER_MEM, WM_SETTEXT, 0, (LPARAM)szText);
277 }
278
279 /* retrieve current display mode */
280 DevMode.dmSize = sizeof(DEVMODE);
281 if (EnumDisplaySettingsW(pDispDevice->DeviceName, ENUM_CURRENT_SETTINGS, &DevMode))
282 {
283 szFormat[0] = L'\0';
284 if (LoadStringW(hInst, IDS_FORMAT_ADAPTER_MODE, szFormat, sizeof(szFormat)/sizeof(WCHAR)))
285 szFormat[(sizeof(szFormat)/sizeof(WCHAR))-1] = L'\0';
286 wsprintfW(szText, szFormat, DevMode.dmPelsWidth, DevMode.dmPelsHeight, DevMode.dmBitsPerPel, DevMode.dmDisplayFrequency);
287 SendDlgItemMessageW(hwndDlg, IDC_STATIC_ADAPTER_MODE, WM_SETTEXT, 0, (LPARAM)szText);
288 }
289
290 /* query attached monitor */
291 wcscpy(szText, pDispDevice->DeviceName);
292 ZeroMemory(pDispDevice, sizeof(DISPLAY_DEVICEW));
293 pDispDevice->cb = sizeof(DISPLAY_DEVICEW);
294 if (EnumDisplayDevicesW(szText, 0, pDispDevice, 0))
295 {
296 /* set monitor name */
297 SendDlgItemMessageW(hwndDlg, IDC_STATIC_ADAPTER_MONITOR, WM_SETTEXT, 0, (LPARAM)pDispDevice->DeviceString);
298 }
299
300 hDlgCtrls[0] = GetDlgItem(hwndDlg, IDC_STATIC_ADAPTER_ID);
301 hDlgCtrls[1] = GetDlgItem(hwndDlg, IDC_STATIC_ADAPTER_VENDOR);
302 hDlgCtrls[2] = GetDlgItem(hwndDlg, IDC_STATIC_ADAPTER_DRIVER);
303 hDlgCtrls[3] = GetDlgItem(hwndDlg, IDC_STATIC_ADAPTER_VERSION);
304 hDlgCtrls[4] = GetDlgItem(hwndDlg, IDC_STATIC_ADAPTER_DATE);
305
306 SetDeviceDetails(hDlgCtrls, &GUID_DEVCLASS_DISPLAY, NULL);
307 return TRUE;
308 }
309
310 void InitializeDisplayAdapters(PDXDIAG_CONTEXT pContext)
311 {
312 DISPLAY_DEVICEW DispDevice;
313 HWND * hDlgs;
314 HWND hwndDlg;
315 WCHAR szDisplay[20];
316 WCHAR szText[30];
317 DWORD dwOffset = 0;
318
319 while(TRUE)
320 {
321 ZeroMemory(&DispDevice, sizeof(DISPLAY_DEVICEW));
322 DispDevice.cb = sizeof(DISPLAY_DEVICEW);
323 if (!EnumDisplayDevicesW(NULL, pContext->NumDisplayAdapter + dwOffset, &DispDevice, 0))
324 return;
325
326 /* skip devices not attached to the desktop and mirror drivers */
327 if (!(DispDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) || (DispDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
328 {
329 dwOffset++;
330 continue;
331 }
332 if (pContext->NumDisplayAdapter)
333 hDlgs = HeapReAlloc(GetProcessHeap(), 0, pContext->hDisplayWnd, (pContext->NumDisplayAdapter + 1) * sizeof(HWND));
334 else
335 hDlgs = HeapAlloc(GetProcessHeap(), 0, (pContext->NumDisplayAdapter + 1) * sizeof(HWND));
336
337 if (!hDlgs)
338 break;
339
340 pContext->hDisplayWnd = hDlgs;
341 hwndDlg = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_DISPLAY_DIALOG), pContext->hMainDialog, DisplayPageWndProc, (LPARAM)pContext);
342 if (!hwndDlg)
343 break;
344
345 /* initialize the dialog */
346 InitializeDialog(hwndDlg, &DispDevice);
347
348 szDisplay[0] = L'\0';
349 LoadStringW(hInst, IDS_DISPLAY_DIALOG, szDisplay, sizeof(szDisplay)/sizeof(WCHAR));
350 szDisplay[(sizeof(szDisplay)/sizeof(WCHAR))-1] = L'\0';
351
352 wsprintfW (szText, L"%s %u", szDisplay, pContext->NumDisplayAdapter + 1);
353 InsertTabCtrlItem(GetDlgItem(pContext->hMainDialog, IDC_TAB_CONTROL), pContext->NumDisplayAdapter + 1, szText);
354
355 hDlgs[pContext->NumDisplayAdapter] = hwndDlg;
356 pContext->NumDisplayAdapter++;
357 }
358
359
360 }
361
362
363 INT_PTR CALLBACK
364 DisplayPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
365 {
366 RECT rect;
367 PDXDIAG_CONTEXT pContext = (PDXDIAG_CONTEXT)GetWindowLongPtr(hDlg, DWLP_USER);
368 switch (message)
369 {
370 case WM_INITDIALOG:
371 {
372 pContext = (PDXDIAG_CONTEXT) lParam;
373 SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pContext);
374 SetWindowPos(hDlg, NULL, 10, 32, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
375 return TRUE;
376 }
377 case WM_COMMAND:
378 {
379 switch(LOWORD(wParam))
380 {
381 case IDC_BUTTON_TESTDD:
382 GetWindowRect(pContext->hMainDialog, &rect);
383 /* FIXME log result errors */
384 DDTests();
385 SetWindowPos(pContext->hMainDialog, NULL, rect.left, rect.top, rect.right, rect.bottom, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
386 break;
387 }
388 break;
389 }
390 }
391
392 return FALSE;
393 }