1 /*
2 * ReactOS Device Manager Applet
3 * Copyright (C) 2004 - 2005 ReactOS Team
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 /*
20 *
21 * PROJECT: ReactOS devmgr.dll
22 * FILE: lib/devmgr/advprop.c
23 * PURPOSE: ReactOS Device Manager
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
25 * Ged Murphy <gedmurphy@reactos.org>
26 * UPDATE HISTORY:
27 * 04-04-2004 Created
28 */
29
30 #include "precomp.h"
31 #include "properties.h"
32 #include "resource.h"
33
34 #include <winver.h>
35
36 #define PDCAP_D0_SUPPORTED 0x00000001
37 #define PDCAP_D1_SUPPORTED 0x00000002
38 #define PDCAP_D2_SUPPORTED 0x00000004
39 #define PDCAP_D3_SUPPORTED 0x00000008
40 #define PDCAP_WAKE_FROM_D0_SUPPORTED 0x00000010
41 #define PDCAP_WAKE_FROM_D1_SUPPORTED 0x00000020
42 #define PDCAP_WAKE_FROM_D2_SUPPORTED 0x00000040
43 #define PDCAP_WAKE_FROM_D3_SUPPORTED 0x00000080
44 #define PDCAP_WARM_EJECT_SUPPORTED 0x00000100
45
46 typedef struct CM_Power_Data_s
47 {
48 ULONG PD_Size;
49 DEVICE_POWER_STATE PD_MostRecentPowerState;
50 ULONG PD_Capabilities;
51 ULONG PD_D1Latency;
52 ULONG PD_D2Latency;
53 ULONG PD_D3Latency;
54 DEVICE_POWER_STATE PD_PowerStateMapping[PowerSystemMaximum];
55 SYSTEM_POWER_STATE PD_DeepestSystemWake;
56 } CM_POWER_DATA, *PCM_POWER_DATA;
57
58
59 static UINT WINAPI
EnumDeviceDriverFilesCallback(IN PVOID Context,IN UINT Notification,IN UINT_PTR Param1,IN UINT_PTR Param2)60 EnumDeviceDriverFilesCallback(IN PVOID Context,
61 IN UINT Notification,
62 IN UINT_PTR Param1,
63 IN UINT_PTR Param2)
64 {
65 LVITEM li;
66 PENUMDRIVERFILES_CONTEXT EnumDriverFilesContext = (PENUMDRIVERFILES_CONTEXT)Context;
67
68 li.mask = LVIF_TEXT | LVIF_STATE;
69 li.iItem = EnumDriverFilesContext->nCount++;
70 li.iSubItem = 0;
71 li.state = (li.iItem == 0 ? LVIS_SELECTED : 0);
72 li.stateMask = LVIS_SELECTED;
73 li.pszText = (LPWSTR)Param1;
74 (void)ListView_InsertItem(EnumDriverFilesContext->hDriversListView,
75 &li);
76 return NO_ERROR;
77 }
78
79
80 static VOID
UpdateDriverDetailsDlg(IN HWND hwndDlg,IN HWND hDriversListView,IN PDEVADVPROP_INFO dap)81 UpdateDriverDetailsDlg(IN HWND hwndDlg,
82 IN HWND hDriversListView,
83 IN PDEVADVPROP_INFO dap)
84 {
85 HDEVINFO DeviceInfoSet;
86 PSP_DEVINFO_DATA DeviceInfoData;
87 SP_DRVINFO_DATA DriverInfoData;
88 ENUMDRIVERFILES_CONTEXT EnumDriverFilesContext;
89
90 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
91 {
92 DeviceInfoSet = dap->CurrentDeviceInfoSet;
93 DeviceInfoData = &dap->CurrentDeviceInfoData;
94 }
95 else
96 {
97 DeviceInfoSet = dap->DeviceInfoSet;
98 DeviceInfoData = &dap->DeviceInfoData;
99 }
100
101 /* set the device image */
102 SendDlgItemMessage(hwndDlg,
103 IDC_DEVICON,
104 STM_SETICON,
105 (WPARAM)dap->hDevIcon,
106 0);
107
108 /* set the device name edit control text */
109 SetDlgItemText(hwndDlg,
110 IDC_DEVNAME,
111 dap->szDevName);
112
113 /* fill the driver files list view */
114 EnumDriverFilesContext.hDriversListView = hDriversListView;
115 EnumDriverFilesContext.nCount = 0;
116
117 (void)ListView_DeleteAllItems(EnumDriverFilesContext.hDriversListView);
118 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
119 if (FindCurrentDriver(DeviceInfoSet,
120 DeviceInfoData,
121 &DriverInfoData) &&
122 SetupDiSetSelectedDriver(DeviceInfoSet,
123 DeviceInfoData,
124 &DriverInfoData))
125 {
126 HSPFILEQ queueHandle;
127
128 queueHandle = SetupOpenFileQueue();
129 if (queueHandle != (HSPFILEQ)INVALID_HANDLE_VALUE)
130 {
131 SP_DEVINSTALL_PARAMS DeviceInstallParams = {0};
132 DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
133 if (SetupDiGetDeviceInstallParams(DeviceInfoSet,
134 DeviceInfoData,
135 &DeviceInstallParams))
136 {
137 DeviceInstallParams.FileQueue = queueHandle;
138 DeviceInstallParams.Flags |= DI_NOVCP;
139
140 if (SetupDiSetDeviceInstallParams(DeviceInfoSet,
141 DeviceInfoData,
142 &DeviceInstallParams) &&
143 SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES,
144 DeviceInfoSet,
145 DeviceInfoData))
146 {
147 DWORD scanResult;
148 RECT rcClient;
149 LVCOLUMN lvc;
150
151 /* enumerate the driver files */
152 SetupScanFileQueue(queueHandle,
153 SPQ_SCAN_USE_CALLBACK,
154 NULL,
155 EnumDeviceDriverFilesCallback,
156 &EnumDriverFilesContext,
157 &scanResult);
158
159 /* update the list view column width */
160 GetClientRect(hDriversListView,
161 &rcClient);
162 lvc.mask = LVCF_WIDTH;
163 lvc.cx = rcClient.right;
164 (void)ListView_SetColumn(hDriversListView,
165 0,
166 &lvc);
167
168 /* highlight the first item from list */
169 if (ListView_GetSelectedCount(hDriversListView) != 0)
170 {
171 ListView_SetItemState(hDriversListView,
172 0,
173 LVIS_FOCUSED | LVIS_SELECTED,
174 LVIS_FOCUSED | LVIS_SELECTED);
175 }
176 }
177 }
178
179 SetupCloseFileQueue(queueHandle);
180 }
181 }
182 }
183
184
185 static VOID
UpdateDriverVersionInfoDetails(IN HWND hwndDlg,IN LPCWSTR lpszDriverPath)186 UpdateDriverVersionInfoDetails(IN HWND hwndDlg,
187 IN LPCWSTR lpszDriverPath)
188 {
189 DWORD dwHandle;
190 DWORD dwVerInfoSize;
191 LPVOID lpData = NULL;
192 LPVOID lpInfo;
193 UINT uInfoLen;
194 DWORD dwLangId;
195 WCHAR szLangInfo[255];
196 WCHAR szLangPath[MAX_PATH];
197 LPWSTR lpCompanyName = NULL;
198 LPWSTR lpFileVersion = NULL;
199 LPWSTR lpLegalCopyright = NULL;
200 LPWSTR lpDigitalSigner = NULL;
201 UINT uBufLen;
202 WCHAR szNotAvailable[255];
203
204 /* extract version info from selected file */
205 dwVerInfoSize = GetFileVersionInfoSize(lpszDriverPath,
206 &dwHandle);
207 if (!dwVerInfoSize)
208 goto done;
209
210 lpData = HeapAlloc(GetProcessHeap(),
211 HEAP_ZERO_MEMORY,
212 dwVerInfoSize);
213 if (!lpData)
214 goto done;
215
216 if (!GetFileVersionInfo(lpszDriverPath,
217 dwHandle,
218 dwVerInfoSize,
219 lpData))
220 goto done;
221
222 if (!VerQueryValue(lpData,
223 L"\\VarFileInfo\\Translation",
224 &lpInfo,
225 &uInfoLen))
226 goto done;
227
228 dwLangId = *(LPDWORD)lpInfo;
229 swprintf(szLangInfo, L"\\StringFileInfo\\%04x%04x\\",
230 LOWORD(dwLangId), HIWORD(dwLangId));
231
232 /* read CompanyName */
233 wcscpy(szLangPath, szLangInfo);
234 wcscat(szLangPath, L"CompanyName");
235
236 VerQueryValue(lpData,
237 szLangPath,
238 (void **)&lpCompanyName,
239 (PUINT)&uBufLen);
240
241 /* read FileVersion */
242 wcscpy(szLangPath, szLangInfo);
243 wcscat(szLangPath, L"FileVersion");
244
245 VerQueryValue(lpData,
246 szLangPath,
247 (void **)&lpFileVersion,
248 (PUINT)&uBufLen);
249
250 /* read LegalTrademarks */
251 wcscpy(szLangPath, szLangInfo);
252 wcscat(szLangPath, L"LegalCopyright");
253
254 VerQueryValue(lpData,
255 szLangPath,
256 (void **)&lpLegalCopyright,
257 (PUINT)&uBufLen);
258
259 /* TODO: read digital signer info */
260
261 done:
262 if (!LoadString(hDllInstance,
263 IDS_NOTAVAILABLE,
264 szNotAvailable,
265 sizeof(szNotAvailable) / sizeof(WCHAR)))
266 {
267 wcscpy(szNotAvailable, L"n/a");
268 }
269
270 /* update labels */
271 if (!lpCompanyName)
272 lpCompanyName = szNotAvailable;
273 SetDlgItemText(hwndDlg,
274 IDC_FILEPROVIDER,
275 lpCompanyName);
276
277 if (!lpFileVersion)
278 lpFileVersion = szNotAvailable;
279 SetDlgItemText(hwndDlg,
280 IDC_FILEVERSION,
281 lpFileVersion);
282
283 if (!lpLegalCopyright)
284 lpLegalCopyright = szNotAvailable;
285 SetDlgItemText(hwndDlg,
286 IDC_FILECOPYRIGHT,
287 lpLegalCopyright);
288
289 if (!lpDigitalSigner)
290 lpDigitalSigner = szNotAvailable;
291 SetDlgItemText(hwndDlg,
292 IDC_DIGITALSIGNER,
293 lpDigitalSigner);
294
295 /* release version info */
296 if (lpData)
297 HeapFree(GetProcessHeap(),
298 0,
299 lpData);
300 }
301
302
303 static INT_PTR
304 CALLBACK
DriverDetailsDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)305 DriverDetailsDlgProc(IN HWND hwndDlg,
306 IN UINT uMsg,
307 IN WPARAM wParam,
308 IN LPARAM lParam)
309 {
310 PDEVADVPROP_INFO dap;
311 INT_PTR Ret = FALSE;
312
313 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER);
314
315 if (dap != NULL || uMsg == WM_INITDIALOG)
316 {
317 switch (uMsg)
318 {
319 case WM_COMMAND:
320 {
321 switch (LOWORD(wParam))
322 {
323 case IDOK:
324 case IDCANCEL:
325 {
326 EndDialog(hwndDlg,
327 IDOK);
328 break;
329 }
330 }
331 break;
332 }
333
334 case WM_CLOSE:
335 {
336 EndDialog(hwndDlg,
337 IDCANCEL);
338 break;
339 }
340
341 case WM_INITDIALOG:
342 {
343 LV_COLUMN lvc;
344 HWND hDriversListView;
345 WCHAR szBuffer[260];
346
347 dap = (PDEVADVPROP_INFO)lParam;
348 if (dap != NULL)
349 {
350 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap);
351
352 hDriversListView = GetDlgItem(hwndDlg,
353 IDC_DRIVERFILES);
354
355 /* add a column to the list view control */
356 lvc.mask = LVCF_FMT | LVCF_WIDTH;
357 lvc.fmt = LVCFMT_LEFT;
358 lvc.cx = 0;
359 (void)ListView_InsertColumn(hDriversListView,
360 0,
361 &lvc);
362
363 UpdateDriverDetailsDlg(hwndDlg,
364 hDriversListView,
365 dap);
366
367 if (ListView_GetItemCount(hDriversListView) == 0)
368 {
369 if (LoadStringW(hDllInstance, IDS_NODRIVERS, szBuffer, _countof(szBuffer)))
370 MessageBoxW(hwndDlg, szBuffer, dap->szDevName, MB_OK);
371 EndDialog(hwndDlg, IDCANCEL);
372 }
373 }
374
375 Ret = TRUE;
376 break;
377 }
378
379 case WM_NOTIFY:
380 {
381 LPNMHDR pnmhdr = (LPNMHDR)lParam;
382
383 switch (pnmhdr->code)
384 {
385 case LVN_ITEMCHANGED:
386 {
387 LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
388 HWND hDriversListView = GetDlgItem(hwndDlg,
389 IDC_DRIVERFILES);
390
391 if (ListView_GetSelectedCount(hDriversListView) == 0)
392 {
393 /* nothing is selected - empty the labels */
394 SetDlgItemText(hwndDlg,
395 IDC_FILEPROVIDER,
396 NULL);
397 SetDlgItemText(hwndDlg,
398 IDC_FILEVERSION,
399 NULL);
400 SetDlgItemText(hwndDlg,
401 IDC_FILECOPYRIGHT,
402 NULL);
403 SetDlgItemText(hwndDlg,
404 IDC_DIGITALSIGNER,
405 NULL);
406 }
407 else if (pnmv->uNewState != 0)
408 {
409 /* extract version info and update the labels */
410 WCHAR szDriverPath[MAX_PATH];
411
412 ListView_GetItemText(hDriversListView,
413 pnmv->iItem,
414 pnmv->iSubItem,
415 szDriverPath,
416 _countof(szDriverPath));
417
418 UpdateDriverVersionInfoDetails(hwndDlg,
419 szDriverPath);
420 }
421 }
422 }
423 break;
424 }
425 }
426 }
427
428 return Ret;
429 }
430
431
432 static
433 INT_PTR
434 CALLBACK
UninstallDriverDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)435 UninstallDriverDlgProc(IN HWND hwndDlg,
436 IN UINT uMsg,
437 IN WPARAM wParam,
438 IN LPARAM lParam)
439 {
440 PDEVADVPROP_INFO dap;
441 INT_PTR Ret = FALSE;
442
443 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER);
444
445 if (dap != NULL || uMsg == WM_INITDIALOG)
446 {
447 switch (uMsg)
448 {
449 case WM_INITDIALOG:
450 dap = (PDEVADVPROP_INFO)lParam;
451 if (dap != NULL)
452 {
453 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap);
454
455 /* Set the device image */
456 SendDlgItemMessage(hwndDlg,
457 IDC_DEVICON,
458 STM_SETICON,
459 (WPARAM)dap->hDevIcon,
460 0);
461
462 /* Set the device name */
463 SetDlgItemText(hwndDlg,
464 IDC_DEVNAME,
465 dap->szDevName);
466 }
467
468 Ret = TRUE;
469 break;
470
471 case WM_COMMAND:
472 switch (LOWORD(wParam))
473 {
474 case IDOK:
475 EndDialog(hwndDlg, IDOK);
476 break;
477
478 case IDCANCEL:
479 EndDialog(hwndDlg, IDCANCEL);
480 break;
481 }
482 break;
483
484 case WM_CLOSE:
485 EndDialog(hwndDlg, IDCANCEL);
486 break;
487 }
488 }
489
490 return Ret;
491 }
492
493
494 static
495 VOID
UninstallDriver(_In_ HWND hwndDlg,_In_ PDEVADVPROP_INFO dap)496 UninstallDriver(
497 _In_ HWND hwndDlg,
498 _In_ PDEVADVPROP_INFO dap)
499 {
500 SP_REMOVEDEVICE_PARAMS RemoveDevParams;
501
502 if (DialogBoxParam(hDllInstance,
503 MAKEINTRESOURCE(IDD_UNINSTALLDRIVER),
504 hwndDlg,
505 UninstallDriverDlgProc,
506 (ULONG_PTR)dap) == IDCANCEL)
507 return;
508
509 RemoveDevParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
510 RemoveDevParams.ClassInstallHeader.InstallFunction = DIF_REMOVE;
511 RemoveDevParams.Scope = DI_REMOVEDEVICE_GLOBAL;
512 RemoveDevParams.HwProfile = 0;
513
514 SetupDiSetClassInstallParamsW(dap->DeviceInfoSet,
515 &dap->DeviceInfoData,
516 &RemoveDevParams.ClassInstallHeader,
517 sizeof(SP_REMOVEDEVICE_PARAMS));
518
519 SetupDiCallClassInstaller(DIF_REMOVE,
520 dap->DeviceInfoSet,
521 &dap->DeviceInfoData);
522
523 SetupDiSetClassInstallParamsW(dap->DeviceInfoSet,
524 &dap->DeviceInfoData,
525 NULL,
526 0);
527 }
528
529
530 static
531 VOID
UpdateDriver(IN HWND hwndDlg,IN PDEVADVPROP_INFO dap)532 UpdateDriver(
533 IN HWND hwndDlg,
534 IN PDEVADVPROP_INFO dap)
535 {
536 TOKEN_PRIVILEGES Privileges;
537 HANDLE hToken;
538 DWORD dwReboot;
539 BOOL NeedReboot = FALSE;
540
541 // Better use InstallDevInst:
542 // BOOL
543 // WINAPI
544 // InstallDevInst(
545 // HWND hWnd,
546 // LPWSTR wszDeviceId,
547 // BOOL bUpdate,
548 // DWORD *dwReboot);
549 // See: http://comp.os.ms-windows.programmer.win32.narkive.com/J8FTd4KK/signature-of-undocumented-installdevinstex
550
551 if (!InstallDevInst(hwndDlg, dap->szDeviceID, TRUE, &dwReboot))
552 return;
553
554 if (NeedReboot == FALSE)
555 return;
556
557 //FIXME: load text from resource file
558 if (MessageBoxW(hwndDlg, L"Reboot now?", L"Reboot required", MB_YESNO | MB_ICONQUESTION) != IDYES)
559 return;
560
561 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
562 {
563 ERR("OpenProcessToken failed\n");
564 return;
565 }
566
567 /* Get the LUID for the Shutdown privilege */
568 if (!LookupPrivilegeValueW(NULL, SE_SHUTDOWN_NAME, &Privileges.Privileges[0].Luid))
569 {
570 ERR("LookupPrivilegeValue failed\n");
571 CloseHandle(hToken);
572 return;
573 }
574
575 /* Assign the Shutdown privilege to our process */
576 Privileges.PrivilegeCount = 1;
577 Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
578
579 if (!AdjustTokenPrivileges(hToken, FALSE, &Privileges, 0, NULL, NULL))
580 {
581 ERR("AdjustTokenPrivileges failed\n");
582 CloseHandle(hToken);
583 return;
584 }
585
586 /* Finally shut down the system */
587 if (!ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED))
588 {
589 ERR("ExitWindowsEx failed\n");
590 CloseHandle(hToken);
591 }
592 }
593
594
595 static VOID
UpdateDriverDlg(IN HWND hwndDlg,IN PDEVADVPROP_INFO dap)596 UpdateDriverDlg(IN HWND hwndDlg,
597 IN PDEVADVPROP_INFO dap)
598 {
599 HDEVINFO DeviceInfoSet;
600 PSP_DEVINFO_DATA DeviceInfoData;
601 DWORD dwStatus = 0;
602 DWORD dwProblem = 0;
603 CONFIGRET cr;
604
605 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
606 {
607 DeviceInfoSet = dap->CurrentDeviceInfoSet;
608 DeviceInfoData = &dap->CurrentDeviceInfoData;
609 }
610 else
611 {
612 DeviceInfoSet = dap->DeviceInfoSet;
613 DeviceInfoData = &dap->DeviceInfoData;
614 }
615
616 /* set the device image */
617 SendDlgItemMessage(hwndDlg,
618 IDC_DEVICON,
619 STM_SETICON,
620 (WPARAM)dap->hDevIcon,
621 0);
622
623 /* set the device name edit control text */
624 SetDlgItemText(hwndDlg,
625 IDC_DEVNAME,
626 dap->szDevName);
627
628 /* query the driver provider */
629 if (GetDriverProviderString(DeviceInfoSet,
630 DeviceInfoData,
631 dap->szTemp,
632 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
633 {
634 SetDlgItemText(hwndDlg,
635 IDC_DRVPROVIDER,
636 dap->szTemp);
637 }
638
639 /* query the driver date */
640 if (GetDriverDateString(DeviceInfoSet,
641 DeviceInfoData,
642 dap->szTemp,
643 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
644 {
645 SetDlgItemText(hwndDlg,
646 IDC_DRVDATE,
647 dap->szTemp);
648 }
649
650 /* query the driver version */
651 if (GetDriverVersionString(DeviceInfoSet,
652 DeviceInfoData,
653 dap->szTemp,
654 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
655 {
656 SetDlgItemText(hwndDlg,
657 IDC_DRVVERSION,
658 dap->szTemp);
659 }
660
661 /* Disable the Uninstall button if the driver cannot be removed */
662 cr = CM_Get_DevNode_Status_Ex(&dwStatus,
663 &dwProblem,
664 dap->DeviceInfoData.DevInst,
665 0,
666 dap->hMachine);
667 if (cr == CR_SUCCESS)
668 {
669 if ((dwStatus & DN_ROOT_ENUMERATED) != 0 &&
670 (dwStatus & DN_DISABLEABLE) == 0)
671 EnableWindow(GetDlgItem(hwndDlg, IDC_UNINSTALLDRIVER), FALSE);
672 }
673 }
674
675
676 static INT_PTR
677 CALLBACK
AdvProcDriverDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)678 AdvProcDriverDlgProc(IN HWND hwndDlg,
679 IN UINT uMsg,
680 IN WPARAM wParam,
681 IN LPARAM lParam)
682 {
683 PDEVADVPROP_INFO dap;
684 INT_PTR Ret = FALSE;
685
686 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER);
687
688 if (dap != NULL || uMsg == WM_INITDIALOG)
689 {
690 switch (uMsg)
691 {
692 case WM_COMMAND:
693 {
694 switch (LOWORD(wParam))
695 {
696 case IDC_DRIVERDETAILS:
697 DialogBoxParam(hDllInstance,
698 MAKEINTRESOURCE(IDD_DRIVERDETAILS),
699 hwndDlg,
700 DriverDetailsDlgProc,
701 (ULONG_PTR)dap);
702 break;
703
704 case IDC_UPDATEDRIVER:
705 UpdateDriver(hwndDlg, dap);
706 break;
707
708 case IDC_ROLLBACKDRIVER:
709 // FIXME
710 break;
711
712 case IDC_UNINSTALLDRIVER:
713 UninstallDriver(hwndDlg, dap);
714 break;
715 }
716 break;
717 }
718
719 case WM_NOTIFY:
720 {
721 NMHDR *hdr = (NMHDR*)lParam;
722 switch (hdr->code)
723 {
724 case PSN_APPLY:
725 break;
726 }
727 break;
728 }
729
730 case WM_INITDIALOG:
731 {
732 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
733 if (dap != NULL)
734 {
735 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap);
736
737 UpdateDriverDlg(hwndDlg,
738 dap);
739 }
740 EnableWindow(GetDlgItem(hwndDlg, IDC_ROLLBACKDRIVER), FALSE);
741 Ret = TRUE;
742 break;
743 }
744 }
745 }
746
747 return Ret;
748 }
749
750
751 static VOID
SetListViewText(HWND hwnd,INT iItem,LPCWSTR lpText)752 SetListViewText(HWND hwnd,
753 INT iItem,
754 LPCWSTR lpText)
755 {
756 LVITEM li;
757
758 li.mask = LVIF_TEXT | LVIF_STATE;
759 li.iItem = iItem;
760 li.iSubItem = 0;
761 li.state = 0; //(li.iItem == 0 ? LVIS_SELECTED : 0);
762 li.stateMask = LVIS_SELECTED;
763 li.pszText = (LPWSTR)lpText;
764 (void)ListView_InsertItem(hwnd,
765 &li);
766 }
767
768
769 static VOID
UpdateDetailsDlg(IN HWND hwndDlg,IN PDEVADVPROP_INFO dap)770 UpdateDetailsDlg(IN HWND hwndDlg,
771 IN PDEVADVPROP_INFO dap)
772 {
773 HWND hwndComboBox;
774 HWND hwndListView;
775 LV_COLUMN lvc;
776 RECT rcClient;
777
778 UINT i;
779 UINT Properties[] =
780 {
781 IDS_PROP_DEVICEID,
782 IDS_PROP_HARDWAREIDS,
783 IDS_PROP_COMPATIBLEIDS,
784 IDS_PROP_MATCHINGDEVICEID,
785 IDS_PROP_SERVICE,
786 IDS_PROP_ENUMERATOR,
787 IDS_PROP_CAPABILITIES,
788 IDS_PROP_DEVNODEFLAGS,
789 IDS_PROP_CONFIGFLAGS,
790 IDS_PROP_CSCONFIGFLAGS,
791 IDS_PROP_EJECTIONRELATIONS,
792 IDS_PROP_REMOVALRELATIONS,
793 IDS_PROP_BUSRELATIONS,
794 IDS_PROP_DEVUPPERFILTERS,
795 IDS_PROP_DEVLOWERFILTERS,
796 IDS_PROP_CLASSUPPERFILTERS,
797 IDS_PROP_CLASSLOWERFILTERS,
798 IDS_PROP_CLASSINSTALLER,
799 IDS_PROP_CLASSCOINSTALLER,
800 IDS_PROP_DEVICECOINSTALLER,
801 IDS_PROP_FIRMWAREREVISION,
802 IDS_PROP_CURRENTPOWERSTATE,
803 IDS_PROP_POWERCAPABILITIES,
804 IDS_PROP_POWERSTATEMAPPINGS
805 };
806
807
808 /* set the device image */
809 SendDlgItemMessage(hwndDlg,
810 IDC_DEVICON,
811 STM_SETICON,
812 (WPARAM)dap->hDevIcon,
813 0);
814
815 /* set the device name edit control text */
816 SetDlgItemText(hwndDlg,
817 IDC_DEVNAME,
818 dap->szDevName);
819
820
821 hwndComboBox = GetDlgItem(hwndDlg,
822 IDC_DETAILSPROPNAME);
823
824 hwndListView = GetDlgItem(hwndDlg,
825 IDC_DETAILSPROPVALUE);
826
827 for (i = 0; i != sizeof(Properties) / sizeof(Properties[0]); i++)
828 {
829 /* fill in the device usage combo box */
830 if (LoadString(hDllInstance,
831 Properties[i],
832 dap->szTemp,
833 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
834 {
835 SendMessage(hwndComboBox,
836 CB_ADDSTRING,
837 0,
838 (LPARAM)dap->szTemp);
839 }
840 }
841
842
843 GetClientRect(hwndListView,
844 &rcClient);
845
846 /* add a column to the list view control */
847 lvc.mask = LVCF_FMT | LVCF_WIDTH;
848 lvc.fmt = LVCFMT_LEFT;
849 lvc.cx = rcClient.right;
850 (void)ListView_InsertColumn(hwndListView,
851 0,
852 &lvc);
853
854 SendMessage(hwndComboBox,
855 CB_SETCURSEL,
856 0,
857 0);
858
859 SetListViewText(hwndListView, 0, dap->szDeviceID);
860
861 SetFocus(hwndComboBox);
862 }
863
864
865 static VOID
DisplayDevicePropertyText(IN PDEVADVPROP_INFO dap,IN HWND hwndListView,IN DWORD dwProperty)866 DisplayDevicePropertyText(IN PDEVADVPROP_INFO dap,
867 IN HWND hwndListView,
868 IN DWORD dwProperty)
869 {
870 HDEVINFO DeviceInfoSet;
871 PSP_DEVINFO_DATA DeviceInfoData;
872 DWORD dwType;
873 DWORD dwSize;
874 DWORD dwValue;
875 LPBYTE lpBuffer;
876 LPWSTR lpStr;
877 INT len;
878 INT index;
879
880 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
881 {
882 DeviceInfoSet = dap->CurrentDeviceInfoSet;
883 DeviceInfoData = &dap->CurrentDeviceInfoData;
884 }
885 else
886 {
887 DeviceInfoSet = dap->DeviceInfoSet;
888 DeviceInfoData = &dap->DeviceInfoData;
889 }
890
891 dwSize = 0;
892 SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
893 DeviceInfoData,
894 dwProperty,
895 &dwType,
896 NULL,
897 0,
898 &dwSize);
899 if (dwSize == 0)
900 {
901 if (GetLastError() != ERROR_FILE_NOT_FOUND)
902 {
903 swprintf(dap->szTemp, L"Error: Getting the size failed! (Error: %ld)", GetLastError());
904 SetListViewText(hwndListView, 0, dap->szTemp);
905 }
906 return;
907 }
908
909 if (dwType == REG_SZ)
910 dwSize += sizeof(WCHAR);
911
912 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(),
913 HEAP_ZERO_MEMORY,
914 dwSize);
915 if (lpBuffer == NULL)
916 {
917 SetListViewText(hwndListView, 0, L"Error: Allocating the buffer failed!");
918 return;
919 }
920
921 if (SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
922 DeviceInfoData,
923 dwProperty,
924 &dwType,
925 lpBuffer,
926 dwSize,
927 &dwSize))
928 {
929 if (dwType == REG_SZ)
930 {
931 SetListViewText(hwndListView, 0, (LPWSTR)lpBuffer);
932 }
933 else if (dwType == REG_MULTI_SZ)
934 {
935 lpStr = (LPWSTR)lpBuffer;
936 index = 0;
937 while (*lpStr != 0)
938 {
939 len = wcslen(lpStr) + 1;
940
941 SetListViewText(hwndListView, index, lpStr);
942
943 lpStr += len;
944 index++;
945 }
946 }
947 else if (dwType == REG_DWORD)
948 {
949 dwValue = *(DWORD *) lpBuffer;
950
951 switch (dwProperty)
952 {
953 case SPDRP_CAPABILITIES:
954 index = 0;
955 swprintf(dap->szTemp, L"%08lx", dwValue);
956 SetListViewText(hwndListView, index++, dap->szTemp);
957 if (dwValue & CM_DEVCAP_LOCKSUPPORTED)
958 SetListViewText(hwndListView, index++, L"CM_DEVCAP_LOCKSUPPORTED");
959 if (dwValue & CM_DEVCAP_EJECTSUPPORTED)
960 SetListViewText(hwndListView, index++, L"CM_DEVCAP_EJECTSUPPORTED");
961 if (dwValue & CM_DEVCAP_REMOVABLE)
962 SetListViewText(hwndListView, index++, L"CM_DEVCAP_REMOVABLE");
963 if (dwValue & CM_DEVCAP_DOCKDEVICE)
964 SetListViewText(hwndListView, index++, L"CM_DEVCAP_DOCKDEVICE");
965 if (dwValue & CM_DEVCAP_UNIQUEID)
966 SetListViewText(hwndListView, index++, L"CM_DEVCAP_UNIQUEID");
967 if (dwValue & CM_DEVCAP_SILENTINSTALL)
968 SetListViewText(hwndListView, index++, L"CM_DEVCAP_SILENTINSTALL");
969 if (dwValue & CM_DEVCAP_RAWDEVICEOK)
970 SetListViewText(hwndListView, index++, L"CM_DEVCAP_RAWDEVICEOK");
971 if (dwValue & CM_DEVCAP_SURPRISEREMOVALOK)
972 SetListViewText(hwndListView, index++, L"CM_DEVCAP_SURPRISEREMOVALOK");
973 if (dwValue & CM_DEVCAP_HARDWAREDISABLED)
974 SetListViewText(hwndListView, index++, L"CM_DEVCAP_HARDWAREDISABLED");
975 if (dwValue & CM_DEVCAP_NONDYNAMIC)
976 SetListViewText(hwndListView, index++, L"CM_DEVCAP_NONDYNAMIC");
977 break;
978
979 case SPDRP_CONFIGFLAGS:
980 index = 0;
981 swprintf(dap->szTemp, L"%08lx", dwValue);
982 SetListViewText(hwndListView, index++, dap->szTemp);
983 if (dwValue & CONFIGFLAG_DISABLED)
984 SetListViewText(hwndListView, index++, L"CONFIGFLAG_DISABLED");
985 if (dwValue & CONFIGFLAG_REMOVED)
986 SetListViewText(hwndListView, index++, L"CONFIGFLAG_REMOVED");
987 if (dwValue & CONFIGFLAG_MANUAL_INSTALL)
988 SetListViewText(hwndListView, index++, L"CONFIGFLAG_MANUAL_INSTALL");
989 if (dwValue & CONFIGFLAG_IGNORE_BOOT_LC)
990 SetListViewText(hwndListView, index++, L"CONFIGFLAG_IGNORE_BOOT_LC");
991 if (dwValue & CONFIGFLAG_NET_BOOT)
992 SetListViewText(hwndListView, index++, L"CONFIGFLAG_NET_BOOT");
993 if (dwValue & CONFIGFLAG_REINSTALL)
994 SetListViewText(hwndListView, index++, L"CONFIGFLAG_REINSTALL");
995 if (dwValue & CONFIGFLAG_FAILEDINSTALL)
996 SetListViewText(hwndListView, index++, L"CONFIGFLAG_FAILEDINSTALL");
997 if (dwValue & CONFIGFLAG_CANTSTOPACHILD)
998 SetListViewText(hwndListView, index++, L"CONFIGFLAG_CANTSTOPACHILD");
999 if (dwValue & CONFIGFLAG_OKREMOVEROM)
1000 SetListViewText(hwndListView, index++, L"CONFIGFLAG_OKREMOVEROM");
1001 if (dwValue & CONFIGFLAG_NOREMOVEEXIT)
1002 SetListViewText(hwndListView, index++, L"CONFIGFLAG_NOREMOVEEXIT");
1003 break;
1004
1005 default:
1006 swprintf(dap->szTemp, L"0x%08lx", dwValue);
1007 SetListViewText(hwndListView, 0, dap->szTemp);
1008 break;
1009 }
1010 }
1011 else
1012 {
1013 SetListViewText(hwndListView, 0, L"Error: Unsupported value type!");
1014
1015 }
1016 }
1017 else
1018 {
1019 SetListViewText(hwndListView, 0, L"Error: Retrieving the value failed!");
1020 }
1021
1022 HeapFree(GetProcessHeap(),
1023 0,
1024 lpBuffer);
1025 }
1026
1027 static VOID
DisplayDevNodeFlags(IN PDEVADVPROP_INFO dap,IN HWND hwndListView)1028 DisplayDevNodeFlags(IN PDEVADVPROP_INFO dap,
1029 IN HWND hwndListView)
1030 {
1031 DWORD dwStatus = 0;
1032 DWORD dwProblem = 0;
1033 INT index;
1034
1035 CM_Get_DevNode_Status_Ex(&dwStatus,
1036 &dwProblem,
1037 dap->DeviceInfoData.DevInst,
1038 0,
1039 dap->hMachine);
1040
1041 index = 0;
1042 swprintf(dap->szTemp, L"%08lx", dwStatus);
1043 SetListViewText(hwndListView, index++, dap->szTemp);
1044 if (dwStatus & DN_ROOT_ENUMERATED)
1045 SetListViewText(hwndListView, index++, L"DN_ROOT_ENUMERATED");
1046 if (dwStatus & DN_DRIVER_LOADED)
1047 SetListViewText(hwndListView, index++, L"DN_DRIVER_LOADED");
1048 if (dwStatus & DN_ENUM_LOADED)
1049 SetListViewText(hwndListView, index++, L"DN_ENUM_LOADED");
1050 if (dwStatus & DN_STARTED)
1051 SetListViewText(hwndListView, index++, L"DN_STARTED");
1052 if (dwStatus & DN_MANUAL)
1053 SetListViewText(hwndListView, index++, L"DN_MANUAL");
1054 if (dwStatus & DN_NEED_TO_ENUM)
1055 SetListViewText(hwndListView, index++, L"DN_NEED_TO_ENUM");
1056 if (dwStatus & DN_DRIVER_BLOCKED)
1057 SetListViewText(hwndListView, index++, L"DN_DRIVER_BLOCKED");
1058 if (dwStatus & DN_HARDWARE_ENUM)
1059 SetListViewText(hwndListView, index++, L"DN_HARDWARE_ENUM");
1060 if (dwStatus & DN_NEED_RESTART)
1061 SetListViewText(hwndListView, index++, L"DN_NEED_RESTART");
1062 if (dwStatus & DN_CHILD_WITH_INVALID_ID)
1063 SetListViewText(hwndListView, index++, L"DN_CHILD_WITH_INVALID_ID");
1064 if (dwStatus & DN_HAS_PROBLEM)
1065 SetListViewText(hwndListView, index++, L"DN_HAS_PROBLEM");
1066 if (dwStatus & DN_FILTERED)
1067 SetListViewText(hwndListView, index++, L"DN_FILTERED");
1068 if (dwStatus & DN_LEGACY_DRIVER)
1069 SetListViewText(hwndListView, index++, L"DN_LEGACY_DRIVER");
1070 if (dwStatus & DN_DISABLEABLE)
1071 SetListViewText(hwndListView, index++, L"DN_DISABLEABLE");
1072 if (dwStatus & DN_REMOVABLE)
1073 SetListViewText(hwndListView, index++, L"DN_REMOVABLE");
1074 if (dwStatus & DN_PRIVATE_PROBLEM)
1075 SetListViewText(hwndListView, index++, L"DN_PRIVATE_PROBLEM");
1076 if (dwStatus & DN_MF_PARENT)
1077 SetListViewText(hwndListView, index++, L"DN_MF_PARENT");
1078 if (dwStatus & DN_MF_CHILD)
1079 SetListViewText(hwndListView, index++, L"DN_MF_CHILD");
1080 if (dwStatus & DN_WILL_BE_REMOVED)
1081 SetListViewText(hwndListView, index++, L"DN_WILL_BE_REMOVED");
1082
1083 if (dwStatus & DN_NOT_FIRST_TIMEE)
1084 SetListViewText(hwndListView, index++, L"DN_NOT_FIRST_TIMEE");
1085 if (dwStatus & DN_STOP_FREE_RES)
1086 SetListViewText(hwndListView, index++, L"DN_STOP_FREE_RES");
1087 if (dwStatus & DN_REBAL_CANDIDATE)
1088 SetListViewText(hwndListView, index++, L"DN_REBAL_CANDIDATE");
1089 if (dwStatus & DN_BAD_PARTIAL)
1090 SetListViewText(hwndListView, index++, L"DN_BAD_PARTIAL");
1091 if (dwStatus & DN_NT_ENUMERATOR)
1092 SetListViewText(hwndListView, index++, L"DN_NT_ENUMERATOR");
1093 if (dwStatus & DN_NT_DRIVER)
1094 SetListViewText(hwndListView, index++, L"DN_NT_DRIVER");
1095
1096 if (dwStatus & DN_NEEDS_LOCKING)
1097 SetListViewText(hwndListView, index++, L"DN_NEEDS_LOCKING");
1098 if (dwStatus & DN_ARM_WAKEUP)
1099 SetListViewText(hwndListView, index++, L"DN_ARM_WAKEUP");
1100 if (dwStatus & DN_APM_ENUMERATOR)
1101 SetListViewText(hwndListView, index++, L"DN_APM_ENUMERATOR");
1102 if (dwStatus & DN_APM_DRIVER)
1103 SetListViewText(hwndListView, index++, L"DN_APM_DRIVER");
1104 if (dwStatus & DN_SILENT_INSTALL)
1105 SetListViewText(hwndListView, index++, L"DN_SILENT_INSTALL");
1106 if (dwStatus & DN_NO_SHOW_IN_DM)
1107 SetListViewText(hwndListView, index++, L"DN_NO_SHOW_IN_DM");
1108 if (dwStatus & DN_BOOT_LOG_PROB)
1109 SetListViewText(hwndListView, index++, L"DN_BOOT_LOG_PROB");
1110 }
1111
1112
1113 static VOID
DisplayDevNodeEnumerator(IN PDEVADVPROP_INFO dap,IN HWND hwndListView)1114 DisplayDevNodeEnumerator(IN PDEVADVPROP_INFO dap,
1115 IN HWND hwndListView)
1116 {
1117 PSP_DEVINFO_DATA DeviceInfoData;
1118
1119 DWORD dwType = 0;
1120 WCHAR szBuffer[256];
1121 DWORD dwSize = 256 * sizeof(WCHAR);
1122
1123 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1124 {
1125 DeviceInfoData = &dap->CurrentDeviceInfoData;
1126 }
1127 else
1128 {
1129 DeviceInfoData = &dap->DeviceInfoData;
1130 }
1131
1132 CM_Get_DevNode_Registry_Property_ExW(DeviceInfoData->DevInst,
1133 CM_DRP_ENUMERATOR_NAME,
1134 &dwType,
1135 &szBuffer,
1136 &dwSize,
1137 0,
1138 dap->hMachine);
1139
1140 SetListViewText(hwndListView, 0, szBuffer);
1141 }
1142
1143
1144 static VOID
DisplayCsFlags(IN PDEVADVPROP_INFO dap,IN HWND hwndListView)1145 DisplayCsFlags(IN PDEVADVPROP_INFO dap,
1146 IN HWND hwndListView)
1147 {
1148 DWORD dwValue = 0;
1149 INT index;
1150
1151 CM_Get_HW_Prof_Flags_Ex(dap->szDevName,
1152 0, /* current hardware profile */
1153 &dwValue,
1154 0,
1155 dap->hMachine);
1156
1157 index = 0;
1158 swprintf(dap->szTemp, L"%08lx", dwValue);
1159 SetListViewText(hwndListView, index++, dap->szTemp);
1160
1161 if (dwValue & CSCONFIGFLAG_DISABLED)
1162 SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DISABLED");
1163
1164 if (dwValue & CSCONFIGFLAG_DO_NOT_CREATE)
1165 SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DO_NOT_CREATE");
1166
1167 if (dwValue & CSCONFIGFLAG_DO_NOT_START)
1168 SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DO_NOT_START");
1169 }
1170
1171
1172 static VOID
DisplayMatchingDeviceId(IN PDEVADVPROP_INFO dap,IN HWND hwndListView)1173 DisplayMatchingDeviceId(IN PDEVADVPROP_INFO dap,
1174 IN HWND hwndListView)
1175 {
1176 HDEVINFO DeviceInfoSet;
1177 PSP_DEVINFO_DATA DeviceInfoData;
1178 WCHAR szBuffer[256];
1179 HKEY hKey;
1180 DWORD dwSize;
1181 DWORD dwType;
1182
1183 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1184 {
1185 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1186 DeviceInfoData = &dap->CurrentDeviceInfoData;
1187 }
1188 else
1189 {
1190 DeviceInfoSet = dap->DeviceInfoSet;
1191 DeviceInfoData = &dap->DeviceInfoData;
1192 }
1193
1194 hKey = SetupDiOpenDevRegKey(DeviceInfoSet,
1195 DeviceInfoData,
1196 DICS_FLAG_GLOBAL,
1197 0,
1198 DIREG_DRV,
1199 KEY_QUERY_VALUE);
1200 if (hKey != INVALID_HANDLE_VALUE)
1201 {
1202 dwSize = 256 * sizeof(WCHAR);
1203 if (RegQueryValueEx(hKey,
1204 L"MatchingDeviceId",
1205 NULL,
1206 &dwType,
1207 (LPBYTE)szBuffer,
1208 &dwSize) == ERROR_SUCCESS)
1209 {
1210 SetListViewText(hwndListView, 0, szBuffer);
1211 }
1212
1213 RegCloseKey(hKey);
1214 }
1215 }
1216
1217
1218 static VOID
DisplayClassCoinstallers(IN PDEVADVPROP_INFO dap,IN HWND hwndListView)1219 DisplayClassCoinstallers(IN PDEVADVPROP_INFO dap,
1220 IN HWND hwndListView)
1221 {
1222 HDEVINFO DeviceInfoSet;
1223 PSP_DEVINFO_DATA DeviceInfoData;
1224 WCHAR szClassGuid[45];
1225 HKEY hKey = (HKEY)INVALID_HANDLE_VALUE;
1226 DWORD dwSize;
1227 DWORD dwType;
1228 LPBYTE lpBuffer = NULL;
1229 LPWSTR lpStr;
1230 INT index;
1231 INT len;
1232 LONG lError;
1233
1234 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1235 {
1236 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1237 DeviceInfoData = &dap->CurrentDeviceInfoData;
1238 }
1239 else
1240 {
1241 DeviceInfoSet = dap->DeviceInfoSet;
1242 DeviceInfoData = &dap->DeviceInfoData;
1243 }
1244
1245 dwSize = 45 * sizeof(WCHAR);
1246 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
1247 DeviceInfoData,
1248 SPDRP_CLASSGUID,
1249 &dwType,
1250 (LPBYTE)szClassGuid,
1251 dwSize,
1252 &dwSize))
1253 return;
1254
1255 lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1256 L"SYSTEM\\CurrentControlSet\\Control\\CoDeviceInstallers",
1257 0,
1258 GENERIC_READ,
1259 &hKey);
1260 if (lError != ERROR_SUCCESS)
1261 return;
1262
1263 dwSize = 0;
1264 lError = RegQueryValueEx(hKey,
1265 szClassGuid,
1266 NULL,
1267 &dwType,
1268 NULL,
1269 &dwSize);
1270 if (lError != ERROR_SUCCESS)
1271 goto done;
1272
1273 if (dwSize == 0)
1274 goto done;
1275
1276 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(),
1277 HEAP_ZERO_MEMORY,
1278 dwSize);
1279
1280 RegQueryValueEx(hKey,
1281 szClassGuid,
1282 NULL,
1283 &dwType,
1284 lpBuffer,
1285 &dwSize);
1286
1287 lpStr = (LPWSTR)lpBuffer;
1288 index = 0;
1289 while (*lpStr != 0)
1290 {
1291 len = wcslen(lpStr) + 1;
1292
1293 SetListViewText(hwndListView, index, lpStr);
1294
1295 lpStr += len;
1296 index++;
1297 }
1298
1299 done:
1300 if (lpBuffer != NULL)
1301 HeapFree(GetProcessHeap(), 0, lpBuffer);
1302
1303 if (hKey != INVALID_HANDLE_VALUE)
1304 RegCloseKey(hKey);
1305 }
1306
1307
1308 static VOID
DisplayDeviceCoinstallers(IN PDEVADVPROP_INFO dap,IN HWND hwndListView)1309 DisplayDeviceCoinstallers(IN PDEVADVPROP_INFO dap,
1310 IN HWND hwndListView)
1311 {
1312 HDEVINFO DeviceInfoSet;
1313 PSP_DEVINFO_DATA DeviceInfoData;
1314 HKEY hKey;
1315 DWORD dwSize;
1316 DWORD dwType;
1317 LPBYTE lpBuffer;
1318 LPWSTR lpStr;
1319 INT index;
1320 INT len;
1321
1322 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1323 {
1324 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1325 DeviceInfoData = &dap->CurrentDeviceInfoData;
1326 }
1327 else
1328 {
1329 DeviceInfoSet = dap->DeviceInfoSet;
1330 DeviceInfoData = &dap->DeviceInfoData;
1331 }
1332
1333 hKey = SetupDiOpenDevRegKey(DeviceInfoSet,
1334 DeviceInfoData,
1335 DICS_FLAG_GLOBAL,
1336 0,
1337 DIREG_DRV,
1338 KEY_QUERY_VALUE);
1339 if (hKey != INVALID_HANDLE_VALUE)
1340 {
1341 dwSize = 0;
1342 if (RegQueryValueEx(hKey,
1343 L"CoInstallers32",
1344 NULL,
1345 &dwType,
1346 NULL,
1347 &dwSize) == ERROR_SUCCESS &&
1348 dwSize > 0)
1349 {
1350
1351 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(),
1352 HEAP_ZERO_MEMORY,
1353 dwSize);
1354
1355 RegQueryValueEx(hKey,
1356 L"CoInstallers32",
1357 NULL,
1358 &dwType,
1359 lpBuffer,
1360 &dwSize);
1361
1362 lpStr = (LPWSTR)lpBuffer;
1363 index = 0;
1364 while (*lpStr != 0)
1365 {
1366 len = wcslen(lpStr) + 1;
1367
1368 SetListViewText(hwndListView, index, lpStr);
1369
1370 lpStr += len;
1371 index++;
1372 }
1373
1374 HeapFree(GetProcessHeap(),
1375 0,
1376 lpBuffer);
1377 }
1378
1379 RegCloseKey(hKey);
1380 }
1381 }
1382
1383
1384 static VOID
DisplayClassProperties(IN PDEVADVPROP_INFO dap,IN HWND hwndListView,IN LPCWSTR lpProperty)1385 DisplayClassProperties(IN PDEVADVPROP_INFO dap,
1386 IN HWND hwndListView,
1387 IN LPCWSTR lpProperty)
1388 {
1389 HDEVINFO DeviceInfoSet;
1390 PSP_DEVINFO_DATA DeviceInfoData;
1391 WCHAR szClassGuid[45];
1392 DWORD dwSize;
1393 DWORD dwType;
1394 HKEY hKey;
1395 GUID ClassGuid;
1396 LPBYTE lpBuffer;
1397 LPWSTR lpStr;
1398 INT index = 0;
1399 INT len;
1400
1401 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1402 {
1403 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1404 DeviceInfoData = &dap->CurrentDeviceInfoData;
1405 }
1406 else
1407 {
1408 DeviceInfoSet = dap->DeviceInfoSet;
1409 DeviceInfoData = &dap->DeviceInfoData;
1410 }
1411
1412 dwSize = 45 * sizeof(WCHAR);
1413 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
1414 DeviceInfoData,
1415 SPDRP_CLASSGUID,
1416 &dwType,
1417 (LPBYTE)szClassGuid,
1418 dwSize,
1419 &dwSize))
1420 return;
1421
1422 pSetupGuidFromString(szClassGuid,
1423 &ClassGuid);
1424
1425 hKey = SetupDiOpenClassRegKey(&ClassGuid,
1426 KEY_QUERY_VALUE);
1427 if (hKey != INVALID_HANDLE_VALUE)
1428 {
1429 dwSize = 0;
1430 if (RegQueryValueEx(hKey,
1431 lpProperty,
1432 NULL,
1433 &dwType,
1434 NULL,
1435 &dwSize) == ERROR_SUCCESS &&
1436 dwSize > 0)
1437 {
1438 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(),
1439 HEAP_ZERO_MEMORY,
1440 dwSize);
1441
1442 RegQueryValueEx(hKey,
1443 lpProperty,
1444 NULL,
1445 &dwType,
1446 lpBuffer,
1447 &dwSize);
1448
1449 if (dwType == REG_SZ)
1450 {
1451 SetListViewText(hwndListView, 0, (LPWSTR)lpBuffer);
1452 }
1453 else if (dwType == REG_MULTI_SZ)
1454 {
1455 lpStr = (LPWSTR)lpBuffer;
1456 index = 0;
1457 while (*lpStr != 0)
1458 {
1459 len = wcslen(lpStr) + 1;
1460
1461 SetListViewText(hwndListView, index, lpStr);
1462
1463 lpStr += len;
1464 index++;
1465 }
1466 }
1467
1468 HeapFree(GetProcessHeap(),
1469 0,
1470 lpBuffer);
1471 }
1472
1473 RegCloseKey(hKey);
1474 }
1475 }
1476
1477
1478 static VOID
DisplayDeviceRelations(IN PDEVADVPROP_INFO dap,IN HWND hwndListView,IN ULONG ulFlags)1479 DisplayDeviceRelations(
1480 IN PDEVADVPROP_INFO dap,
1481 IN HWND hwndListView,
1482 IN ULONG ulFlags)
1483 {
1484 ULONG ulLength = 0;
1485 LPWSTR pszBuffer = NULL, pszStr;
1486 INT index = 0, len;
1487 CONFIGRET ret;
1488
1489 ret = CM_Get_Device_ID_List_Size_ExW(&ulLength,
1490 dap->szDeviceID,
1491 ulFlags,
1492 NULL);
1493 if (ret != CR_SUCCESS)
1494 return;
1495
1496 pszBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(),
1497 HEAP_ZERO_MEMORY,
1498 ulLength * sizeof(WCHAR));
1499 if (pszBuffer == NULL)
1500 return;
1501
1502 ret = CM_Get_Device_ID_List_ExW(dap->szDeviceID,
1503 pszBuffer,
1504 ulLength,
1505 ulFlags,
1506 NULL);
1507 if (ret != CR_SUCCESS)
1508 {
1509 HeapFree(GetProcessHeap(), 0, pszBuffer);
1510 return;
1511 }
1512
1513 pszStr = pszBuffer;
1514 index = 0;
1515 while (*pszStr != 0)
1516 {
1517 len = wcslen(pszStr) + 1;
1518
1519 SetListViewText(hwndListView, index, pszStr);
1520
1521 pszStr += len;
1522 index++;
1523 }
1524
1525 HeapFree(GetProcessHeap(), 0, pszBuffer);
1526 }
1527
1528
1529 static VOID
DisplayCurrentPowerState(IN PDEVADVPROP_INFO dap,IN HWND hwndListView)1530 DisplayCurrentPowerState(
1531 IN PDEVADVPROP_INFO dap,
1532 IN HWND hwndListView)
1533 {
1534 HDEVINFO DeviceInfoSet;
1535 PSP_DEVINFO_DATA DeviceInfoData;
1536 CM_POWER_DATA PowerData;
1537 DWORD dwSize, dwType;
1538 PCWSTR lpText = NULL;
1539
1540 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1541 {
1542 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1543 DeviceInfoData = &dap->CurrentDeviceInfoData;
1544 }
1545 else
1546 {
1547 DeviceInfoSet = dap->DeviceInfoSet;
1548 DeviceInfoData = &dap->DeviceInfoData;
1549 }
1550
1551 dwSize = sizeof(CM_POWER_DATA);
1552 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
1553 DeviceInfoData,
1554 SPDRP_DEVICE_POWER_DATA,
1555 &dwType,
1556 (LPBYTE)&PowerData,
1557 dwSize,
1558 &dwSize))
1559 return;
1560
1561 switch (PowerData.PD_MostRecentPowerState)
1562 {
1563 // case PowerDeviceUnspecified:
1564
1565 case PowerDeviceD0:
1566 lpText = L"D0";
1567 break;
1568
1569 case PowerDeviceD1:
1570 lpText = L"D1";
1571 break;
1572
1573 case PowerDeviceD2:
1574 lpText = L"D2";
1575 break;
1576
1577 case PowerDeviceD3:
1578 lpText = L"D3";
1579 break;
1580
1581 default:
1582 break;
1583 }
1584
1585 if (lpText != NULL)
1586 SetListViewText(hwndListView, 0, lpText);
1587 }
1588
1589
1590 static VOID
DisplayPowerCapabilities(IN PDEVADVPROP_INFO dap,IN HWND hwndListView)1591 DisplayPowerCapabilities(
1592 IN PDEVADVPROP_INFO dap,
1593 IN HWND hwndListView)
1594 {
1595 HDEVINFO DeviceInfoSet;
1596 PSP_DEVINFO_DATA DeviceInfoData;
1597 CM_POWER_DATA PowerData;
1598 DWORD dwSize, dwType;
1599 INT index = 0;
1600
1601 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1602 {
1603 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1604 DeviceInfoData = &dap->CurrentDeviceInfoData;
1605 }
1606 else
1607 {
1608 DeviceInfoSet = dap->DeviceInfoSet;
1609 DeviceInfoData = &dap->DeviceInfoData;
1610 }
1611
1612 dwSize = sizeof(CM_POWER_DATA);
1613 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
1614 DeviceInfoData,
1615 SPDRP_DEVICE_POWER_DATA,
1616 &dwType,
1617 (LPBYTE)&PowerData,
1618 dwSize,
1619 &dwSize))
1620 return;
1621
1622 if (PowerData.PD_Capabilities & PDCAP_D0_SUPPORTED)
1623 SetListViewText(hwndListView, index++, L"PDCAP_D0_SUPPORTED");
1624
1625 if (PowerData.PD_Capabilities & PDCAP_D1_SUPPORTED)
1626 SetListViewText(hwndListView, index++, L"PDCAP_D1_SUPPORTED");
1627
1628 if (PowerData.PD_Capabilities & PDCAP_D2_SUPPORTED)
1629 SetListViewText(hwndListView, index++, L"PDCAP_D2_SUPPORTED");
1630
1631 if (PowerData.PD_Capabilities & PDCAP_D3_SUPPORTED)
1632 SetListViewText(hwndListView, index++, L"PDCAP_D3_SUPPORTED");
1633
1634 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D0_SUPPORTED)
1635 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D0_SUPPORTED");
1636
1637 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D1_SUPPORTED)
1638 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D1_SUPPORTED");
1639
1640 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D2_SUPPORTED)
1641 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D2_SUPPORTED");
1642
1643 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D3_SUPPORTED)
1644 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D3_SUPPORTED");
1645
1646 if (PowerData.PD_Capabilities & PDCAP_WARM_EJECT_SUPPORTED)
1647 SetListViewText(hwndListView, index++, L"PDCAP_WARM_EJECT_SUPPORTED");
1648 }
1649
1650
1651 static VOID
DisplayPowerStateMappings(IN PDEVADVPROP_INFO dap,IN HWND hwndListView)1652 DisplayPowerStateMappings(
1653 IN PDEVADVPROP_INFO dap,
1654 IN HWND hwndListView)
1655 {
1656 HDEVINFO DeviceInfoSet;
1657 PSP_DEVINFO_DATA DeviceInfoData;
1658 CM_POWER_DATA PowerData;
1659 DWORD dwSize, dwType;
1660 INT i;
1661 DEVICE_POWER_STATE PowerState;
1662 WCHAR szSystemStateBuffer[40];
1663 WCHAR szDeviceStateBuffer[40];
1664 WCHAR szOutBuffer[100];
1665
1666 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1667 {
1668 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1669 DeviceInfoData = &dap->CurrentDeviceInfoData;
1670 }
1671 else
1672 {
1673 DeviceInfoSet = dap->DeviceInfoSet;
1674 DeviceInfoData = &dap->DeviceInfoData;
1675 }
1676
1677 dwSize = sizeof(CM_POWER_DATA);
1678 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
1679 DeviceInfoData,
1680 SPDRP_DEVICE_POWER_DATA,
1681 &dwType,
1682 (LPBYTE)&PowerData,
1683 dwSize,
1684 &dwSize))
1685 return;
1686
1687 for (i = PowerSystemWorking; i < PowerSystemMaximum; i++)
1688 {
1689 PowerState = PowerData.PD_PowerStateMapping[i];
1690 if ((PowerState >= PowerDeviceUnspecified) && (PowerState <= PowerDeviceD3))
1691 {
1692 swprintf(szSystemStateBuffer, L"S%u", i - 1);
1693
1694 switch (PowerState)
1695 {
1696 case PowerDeviceUnspecified:
1697 wcscpy(szDeviceStateBuffer, L"Not specified");
1698 break;
1699
1700 case PowerDeviceD0:
1701 wcscpy(szDeviceStateBuffer, L"D0");
1702 break;
1703
1704 case PowerDeviceD1:
1705 wcscpy(szDeviceStateBuffer, L"D1");
1706 break;
1707
1708 case PowerDeviceD2:
1709 wcscpy(szDeviceStateBuffer, L"D2");
1710 break;
1711
1712 case PowerDeviceD3:
1713 wcscpy(szDeviceStateBuffer, L"D3");
1714 break;
1715
1716 default:
1717 break;
1718 }
1719
1720 swprintf(szOutBuffer, L"%s -> %s", szSystemStateBuffer, szDeviceStateBuffer);
1721 SetListViewText(hwndListView, i, szOutBuffer);
1722 }
1723 }
1724 }
1725
1726
1727 static VOID
DisplayDeviceProperties(IN PDEVADVPROP_INFO dap,IN HWND hwndComboBox,IN HWND hwndListView)1728 DisplayDeviceProperties(IN PDEVADVPROP_INFO dap,
1729 IN HWND hwndComboBox,
1730 IN HWND hwndListView)
1731 {
1732 INT Index;
1733
1734 Index = (INT)SendMessage(hwndComboBox,
1735 CB_GETCURSEL,
1736 0,
1737 0);
1738 if (Index == CB_ERR)
1739 return;
1740
1741 (void)ListView_DeleteAllItems(hwndListView);
1742
1743 switch (Index)
1744 {
1745 case 0: /* Device ID */
1746 SetListViewText(hwndListView, 0, dap->szDeviceID);
1747 break;
1748
1749 case 1: /* Hardware ID */
1750 DisplayDevicePropertyText(dap,
1751 hwndListView,
1752 SPDRP_HARDWAREID);
1753 break;
1754
1755 case 2: /* Compatible IDs */
1756 DisplayDevicePropertyText(dap,
1757 hwndListView,
1758 SPDRP_COMPATIBLEIDS);
1759 break;
1760
1761 case 3: /* Matching ID */
1762 DisplayMatchingDeviceId(dap,
1763 hwndListView);
1764 break;
1765
1766 case 4: /* Service */
1767 DisplayDevicePropertyText(dap,
1768 hwndListView,
1769 SPDRP_SERVICE);
1770 break;
1771
1772 case 5: /* Enumerator */
1773 DisplayDevNodeEnumerator(dap,
1774 hwndListView);
1775 break;
1776
1777 case 6: /* Capabilities */
1778 DisplayDevicePropertyText(dap,
1779 hwndListView,
1780 SPDRP_CAPABILITIES);
1781 break;
1782
1783 case 7: /* Devnode Flags */
1784 DisplayDevNodeFlags(dap,
1785 hwndListView);
1786 break;
1787
1788 case 8: /* Config Flags */
1789 DisplayDevicePropertyText(dap,
1790 hwndListView,
1791 SPDRP_CONFIGFLAGS);
1792 break;
1793
1794 case 9: /* CSConfig Flags */
1795 DisplayCsFlags(dap,
1796 hwndListView);
1797 break;
1798
1799 case 10: /* Ejection relation */
1800 DisplayDeviceRelations(dap,
1801 hwndListView,
1802 CM_GETIDLIST_FILTER_EJECTRELATIONS);
1803 break;
1804
1805 case 11: /* Removal relations */
1806 DisplayDeviceRelations(dap,
1807 hwndListView,
1808 CM_GETIDLIST_FILTER_REMOVALRELATIONS);
1809 break;
1810
1811 case 12: /* Bus relation */
1812 DisplayDeviceRelations(dap,
1813 hwndListView,
1814 CM_GETIDLIST_FILTER_BUSRELATIONS);
1815 break;
1816
1817 case 13: /* Device Upper Filters */
1818 DisplayDevicePropertyText(dap,
1819 hwndListView,
1820 SPDRP_UPPERFILTERS);
1821 break;
1822
1823 case 14: /* Device Lower Filters */
1824 DisplayDevicePropertyText(dap,
1825 hwndListView,
1826 SPDRP_LOWERFILTERS);
1827 break;
1828
1829 case 15: /* Class Upper Filters */
1830 DisplayClassProperties(dap,
1831 hwndListView,
1832 L"UpperFilters");
1833 break;
1834
1835 case 16: /* Class Lower Filters */
1836 DisplayClassProperties(dap,
1837 hwndListView,
1838 L"LowerFilters");
1839 break;
1840
1841 case 17: /* Class Installer */
1842 DisplayClassProperties(dap,
1843 hwndListView,
1844 L"Installer32");
1845 break;
1846
1847 case 18: /* Class Coinstaller */
1848 DisplayClassCoinstallers(dap,
1849 hwndListView);
1850 break;
1851
1852 case 19: /* Device Coinstaller */
1853 DisplayDeviceCoinstallers(dap,
1854 hwndListView);
1855 break;
1856
1857 #if 0
1858 case 20: /* Firmware Revision */
1859 break;
1860 #endif
1861
1862 case 21: /* Current Power State */
1863 DisplayCurrentPowerState(dap,
1864 hwndListView);
1865 break;
1866
1867 case 22: /* Power Capabilities */
1868 DisplayPowerCapabilities(dap,
1869 hwndListView);
1870 break;
1871
1872 case 23: /* Power State Mappings */
1873 DisplayPowerStateMappings(dap,
1874 hwndListView);
1875 break;
1876
1877 default:
1878 SetListViewText(hwndListView, 0, L"<Not implemented yet>");
1879 break;
1880 }
1881 }
1882
1883
1884 static INT_PTR
1885 CALLBACK
AdvProcDetailsDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)1886 AdvProcDetailsDlgProc(IN HWND hwndDlg,
1887 IN UINT uMsg,
1888 IN WPARAM wParam,
1889 IN LPARAM lParam)
1890 {
1891 PDEVADVPROP_INFO dap;
1892 INT_PTR Ret = FALSE;
1893
1894 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER);
1895
1896 if (dap != NULL || uMsg == WM_INITDIALOG)
1897 {
1898 switch (uMsg)
1899 {
1900 case WM_CONTEXTMENU:
1901 {
1902 if ((HWND)wParam == GetDlgItem(hwndDlg, IDC_DETAILSPROPVALUE))
1903 {
1904 WCHAR szColName[255];
1905
1906 if (!LoadStringW(hDllInstance, IDS_COPY, szColName, _countof(szColName)))
1907 break;
1908
1909 INT nSelectedItems = ListView_GetSelectedCount((HWND)wParam);
1910 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1911 HMENU hPopup = CreatePopupMenu();
1912
1913 AppendMenuW(hPopup, MF_STRING, IDS_MENU_COPY, szColName);
1914
1915 if (nSelectedItems <= 0)
1916 EnableMenuItem(hPopup, IDS_MENU_COPY, MF_BYCOMMAND | MF_GRAYED);
1917
1918 TrackPopupMenu(hPopup, TPM_LEFTALIGN, pt.x, pt.y, 0, hwndDlg, NULL);
1919 DestroyMenu(hPopup);
1920 Ret = TRUE;
1921 }
1922 break;
1923 }
1924
1925 case WM_COMMAND:
1926 {
1927 switch (LOWORD(wParam))
1928 {
1929 case IDC_DETAILSPROPNAME:
1930 if (HIWORD(wParam) == CBN_SELCHANGE)
1931 {
1932 DisplayDeviceProperties(dap,
1933 GetDlgItem(hwndDlg, IDC_DETAILSPROPNAME),
1934 GetDlgItem(hwndDlg, IDC_DETAILSPROPVALUE));
1935 }
1936 break;
1937
1938 case IDS_MENU_COPY:
1939 {
1940 HWND hwndListView = GetDlgItem(hwndDlg, IDC_DETAILSPROPVALUE);
1941 INT nSelectedItems = ListView_GetSelectedCount(hwndListView);
1942 INT nSelectedId = ListView_GetSelectionMark(hwndListView);
1943
1944 if (nSelectedId < 0 || nSelectedItems <= 0)
1945 break;
1946
1947 HGLOBAL hGlobal;
1948 LPWSTR pszBuffer;
1949 SIZE_T cchSize = MAX_PATH + 1;
1950
1951 hGlobal = GlobalAlloc(GHND, cchSize * sizeof(WCHAR));
1952 if (!hGlobal)
1953 break;
1954 pszBuffer = (LPWSTR)GlobalLock(hGlobal);
1955 if (!pszBuffer)
1956 {
1957 GlobalFree(hGlobal);
1958 break;
1959 }
1960
1961 ListView_GetItemText(hwndListView,
1962 nSelectedId, 0,
1963 pszBuffer,
1964 cchSize);
1965 /* Ensure NULL-termination */
1966 pszBuffer[cchSize - 1] = UNICODE_NULL;
1967
1968 GlobalUnlock(hGlobal);
1969
1970 if (OpenClipboard(NULL))
1971 {
1972 EmptyClipboard();
1973 SetClipboardData(CF_UNICODETEXT, hGlobal);
1974 CloseClipboard();
1975 Ret = TRUE;
1976 }
1977 else
1978 {
1979 GlobalFree(hGlobal);
1980 }
1981 break;
1982 }
1983 }
1984 break;
1985 }
1986
1987 case WM_NOTIFY:
1988 {
1989 NMHDR *hdr = (NMHDR*)lParam;
1990 switch (hdr->code)
1991 {
1992 case PSN_APPLY:
1993 break;
1994 }
1995 break;
1996 }
1997
1998 case WM_INITDIALOG:
1999 {
2000 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
2001 if (dap != NULL)
2002 {
2003 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap);
2004
2005 UpdateDetailsDlg(hwndDlg,
2006 dap);
2007 }
2008 Ret = TRUE;
2009 break;
2010 }
2011 }
2012 }
2013
2014 return Ret;
2015 }
2016
2017
2018 static VOID
InitDevUsageActions(IN HWND hwndDlg,IN HWND hComboBox,IN PDEVADVPROP_INFO dap)2019 InitDevUsageActions(IN HWND hwndDlg,
2020 IN HWND hComboBox,
2021 IN PDEVADVPROP_INFO dap)
2022 {
2023 INT Index;
2024 UINT i;
2025 UINT Actions[] =
2026 {
2027 IDS_ENABLEDEVICE,
2028 IDS_DISABLEDEVICE,
2029 };
2030
2031 for (i = 0;
2032 i != sizeof(Actions) / sizeof(Actions[0]);
2033 i++)
2034 {
2035 /* fill in the device usage combo box */
2036 if (LoadString(hDllInstance,
2037 Actions[i],
2038 dap->szTemp,
2039 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
2040 {
2041 Index = (INT)SendMessage(hComboBox,
2042 CB_ADDSTRING,
2043 0,
2044 (LPARAM)dap->szTemp);
2045 if (Index != CB_ERR)
2046 {
2047 SendMessage(hComboBox,
2048 CB_SETITEMDATA,
2049 (WPARAM)Index,
2050 (LPARAM)Actions[i]);
2051
2052 switch (Actions[i])
2053 {
2054 case IDS_ENABLEDEVICE:
2055 if (dap->DeviceStarted)
2056 {
2057 SendMessage(hComboBox,
2058 CB_SETCURSEL,
2059 (WPARAM)Index,
2060 0);
2061 }
2062 break;
2063
2064 case IDS_DISABLEDEVICE:
2065 if (!dap->DeviceStarted)
2066 {
2067 SendMessage(hComboBox,
2068 CB_SETCURSEL,
2069 (WPARAM)Index,
2070 0);
2071 }
2072 break;
2073
2074 default:
2075 break;
2076 }
2077 }
2078 }
2079 }
2080 }
2081
2082
2083 static UINT
GetSelectedUsageAction(IN HWND hComboBox)2084 GetSelectedUsageAction(IN HWND hComboBox)
2085 {
2086 INT Index;
2087 UINT Ret = 0;
2088
2089 Index = (INT)SendMessage(hComboBox,
2090 CB_GETCURSEL,
2091 0,
2092 0);
2093 if (Index != CB_ERR)
2094 {
2095 INT iRet = (INT) SendMessage(hComboBox,
2096 CB_GETITEMDATA,
2097 (WPARAM)Index,
2098 0);
2099 if (iRet != CB_ERR)
2100 {
2101 Ret = (UINT)iRet;
2102 }
2103 }
2104
2105 return Ret;
2106 }
2107
2108
2109 static BOOL
ApplyGeneralSettings(IN HWND hwndDlg,IN PDEVADVPROP_INFO dap)2110 ApplyGeneralSettings(IN HWND hwndDlg,
2111 IN PDEVADVPROP_INFO dap)
2112 {
2113 BOOL Ret = FALSE;
2114
2115 if (dap->DeviceUsageChanged && dap->IsAdmin && dap->CanDisable)
2116 {
2117 UINT SelectedUsageAction;
2118 BOOL NeedReboot = FALSE;
2119
2120 SelectedUsageAction = GetSelectedUsageAction(GetDlgItem(hwndDlg,
2121 IDC_DEVUSAGE));
2122 switch (SelectedUsageAction)
2123 {
2124 case IDS_ENABLEDEVICE:
2125 if (!dap->DeviceStarted)
2126 {
2127 Ret = EnableDevice(dap->DeviceInfoSet,
2128 &dap->DeviceInfoData,
2129 TRUE,
2130 0,
2131 &NeedReboot);
2132 }
2133 break;
2134
2135 case IDS_DISABLEDEVICE:
2136 if (dap->DeviceStarted)
2137 {
2138 Ret = EnableDevice(dap->DeviceInfoSet,
2139 &dap->DeviceInfoData,
2140 FALSE,
2141 0,
2142 &NeedReboot);
2143 }
2144 break;
2145
2146 default:
2147 break;
2148 }
2149
2150 if (Ret)
2151 {
2152 if (NeedReboot)
2153 {
2154 /* make PropertySheet() return PSM_REBOOTSYSTEM */
2155 PropSheet_RebootSystem(hwndDlg);
2156 }
2157 }
2158 else
2159 {
2160 /* FIXME - display an error message */
2161 FIXME("Failed to enable/disable device! LastError: %d\n",
2162 GetLastError());
2163 }
2164 }
2165 else
2166 Ret = !dap->DeviceUsageChanged;
2167
2168 /* disable the apply button */
2169 PropSheet_UnChanged(GetParent(hwndDlg),
2170 hwndDlg);
2171 dap->DeviceUsageChanged = FALSE;
2172 return Ret;
2173 }
2174
2175
2176 static VOID
UpdateDevInfo(IN HWND hwndDlg,IN PDEVADVPROP_INFO dap,IN BOOL ReOpen)2177 UpdateDevInfo(IN HWND hwndDlg,
2178 IN PDEVADVPROP_INFO dap,
2179 IN BOOL ReOpen)
2180 {
2181 HWND hDevUsage, hPropSheetDlg, hDevProbBtn;
2182 CONFIGRET cr;
2183 ULONG Status, ProblemNumber;
2184 SP_DEVINSTALL_PARAMS_W InstallParams;
2185 UINT TroubleShootStrId = IDS_TROUBLESHOOTDEV;
2186 BOOL bFlag, bDevActionAvailable = TRUE;
2187 BOOL bDrvInstalled = FALSE;
2188 DWORD iPage;
2189 HDEVINFO DeviceInfoSet = NULL;
2190 PSP_DEVINFO_DATA DeviceInfoData = NULL;
2191 PROPSHEETHEADER psh;
2192 DWORD nDriverPages = 0;
2193 BOOL RecalcPages = FALSE;
2194
2195 hPropSheetDlg = GetParent(hwndDlg);
2196
2197 if (dap->PageInitialized)
2198 {
2199 /* switch to the General page */
2200 PropSheet_SetCurSelByID(hPropSheetDlg,
2201 IDD_DEVICEGENERAL);
2202
2203 /* remove and destroy the existing device property sheet pages */
2204 if (dap->DevPropSheets != NULL)
2205 {
2206 for (iPage = 0;
2207 iPage != dap->nDevPropSheets;
2208 iPage++)
2209 {
2210 if (dap->DevPropSheets[iPage] != NULL)
2211 {
2212 PropSheet_RemovePage(hPropSheetDlg,
2213 (WPARAM) -1,
2214 dap->DevPropSheets[iPage]);
2215 RecalcPages = TRUE;
2216 }
2217 }
2218 }
2219 }
2220
2221 iPage = 0;
2222
2223 if (dap->FreeDevPropSheets)
2224 {
2225 /* don't free the array if it's the one allocated in
2226 DisplayDeviceAdvancedProperties */
2227 HeapFree(GetProcessHeap(),
2228 0,
2229 dap->DevPropSheets);
2230
2231 dap->FreeDevPropSheets = FALSE;
2232 }
2233
2234 dap->DevPropSheets = NULL;
2235 dap->nDevPropSheets = 0;
2236
2237 if (ReOpen)
2238 {
2239 /* create a new device info set and re-open the device */
2240 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
2241 {
2242 SetupDiDestroyDeviceInfoList(dap->CurrentDeviceInfoSet);
2243 }
2244
2245 dap->ParentDevInst = 0;
2246 dap->CurrentDeviceInfoSet = SetupDiCreateDeviceInfoListEx(NULL,
2247 hwndDlg,
2248 dap->lpMachineName,
2249 NULL);
2250 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
2251 {
2252 if (SetupDiOpenDeviceInfo(dap->CurrentDeviceInfoSet,
2253 dap->szDeviceID,
2254 hwndDlg,
2255 0,
2256 &dap->CurrentDeviceInfoData))
2257 {
2258 if (dap->CloseDevInst)
2259 {
2260 SetupDiDestroyDeviceInfoList(dap->DeviceInfoSet);
2261 }
2262
2263 dap->CloseDevInst = TRUE;
2264 dap->DeviceInfoSet = dap->CurrentDeviceInfoSet;
2265 dap->DeviceInfoData = dap->CurrentDeviceInfoData;
2266 dap->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE;
2267 }
2268 else
2269 goto GetParentNode;
2270 }
2271 else
2272 {
2273 GetParentNode:
2274 /* get the parent node from the initial devinst */
2275 CM_Get_Parent_Ex(&dap->ParentDevInst,
2276 dap->DeviceInfoData.DevInst,
2277 0,
2278 dap->hMachine);
2279 }
2280
2281 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
2282 {
2283 DeviceInfoSet = dap->CurrentDeviceInfoSet;
2284 DeviceInfoData = &dap->CurrentDeviceInfoData;
2285 }
2286 else
2287 {
2288 DeviceInfoSet = dap->DeviceInfoSet;
2289 DeviceInfoData = &dap->DeviceInfoData;
2290 }
2291 }
2292 else
2293 {
2294 DeviceInfoSet = dap->DeviceInfoSet;
2295 DeviceInfoData = &dap->DeviceInfoData;
2296 }
2297
2298 dap->HasDriverPage = TRUE;
2299 dap->HasResourcePage = TRUE;
2300 dap->HasPowerPage = TRUE;
2301 if (IsDriverInstalled(DeviceInfoData->DevInst,
2302 dap->hMachine,
2303 &bDrvInstalled) &&
2304 bDrvInstalled)
2305 {
2306 if (SetupDiCallClassInstaller((dap->ShowRemotePages ?
2307 DIF_ADDREMOTEPROPERTYPAGE_ADVANCED :
2308 DIF_ADDPROPERTYPAGE_ADVANCED),
2309 DeviceInfoSet,
2310 DeviceInfoData))
2311 {
2312 /* get install params */
2313 InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
2314 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet,
2315 DeviceInfoData,
2316 &InstallParams))
2317 {
2318 /* zero the flags */
2319 InstallParams.Flags = 0;
2320 InstallParams.FlagsEx = 0;
2321 }
2322
2323 dap->HasDriverPage = !(InstallParams.Flags & DI_DRIVERPAGE_ADDED);
2324 dap->HasResourcePage = !(InstallParams.Flags & DI_RESOURCEPAGE_ADDED);
2325 dap->HasPowerPage = !(InstallParams.FlagsEx & DI_FLAGSEX_POWERPAGE_ADDED);
2326 }
2327 }
2328
2329 /* get the device icon */
2330 if (dap->hDevIcon != NULL)
2331 {
2332 DestroyIcon(dap->hDevIcon);
2333 dap->hDevIcon = NULL;
2334 }
2335 if (!SetupDiLoadClassIcon(&DeviceInfoData->ClassGuid,
2336 &dap->hDevIcon,
2337 NULL))
2338 {
2339 dap->hDevIcon = NULL;
2340 }
2341
2342 /* get the device name */
2343 if (GetDeviceDescriptionString(DeviceInfoSet,
2344 DeviceInfoData,
2345 dap->szDevName,
2346 sizeof(dap->szDevName) / sizeof(dap->szDevName[0])))
2347 {
2348 PropSheet_SetTitle(hPropSheetDlg,
2349 PSH_PROPTITLE,
2350 dap->szDevName);
2351 }
2352
2353 /* set the device image */
2354 SendDlgItemMessage(hwndDlg,
2355 IDC_DEVICON,
2356 STM_SETICON,
2357 (WPARAM)dap->hDevIcon,
2358 0);
2359
2360 /* set the device name edit control text */
2361 SetDlgItemText(hwndDlg,
2362 IDC_DEVNAME,
2363 dap->szDevName);
2364
2365 /* set the device type edit control text */
2366 if (GetDeviceTypeString(DeviceInfoData,
2367 dap->szTemp,
2368 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
2369 {
2370 SetDlgItemText(hwndDlg,
2371 IDC_DEVTYPE,
2372 dap->szTemp);
2373 }
2374
2375 /* set the device manufacturer edit control text */
2376 if (GetDeviceManufacturerString(DeviceInfoSet,
2377 DeviceInfoData,
2378 dap->szTemp,
2379 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
2380 {
2381 SetDlgItemText(hwndDlg,
2382 IDC_DEVMANUFACTURER,
2383 dap->szTemp);
2384 }
2385
2386 /* set the device location edit control text */
2387 if (GetDeviceLocationString(DeviceInfoSet,
2388 DeviceInfoData,
2389 dap->ParentDevInst,
2390 dap->szTemp,
2391 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
2392 {
2393 SetDlgItemText(hwndDlg,
2394 IDC_DEVLOCATION,
2395 dap->szTemp);
2396 }
2397
2398 /* set the device status edit control text */
2399 if (GetDeviceStatusString(DeviceInfoData->DevInst,
2400 dap->hMachine,
2401 dap->szTemp,
2402 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
2403 {
2404 SetDlgItemText(hwndDlg,
2405 IDC_DEVSTATUS,
2406 dap->szTemp);
2407 }
2408
2409 /* set the device troubleshoot button text and disable it if necessary */
2410 hDevProbBtn = GetDlgItem(hwndDlg,
2411 IDC_DEVPROBLEM);
2412 cr = CM_Get_DevNode_Status_Ex(&Status,
2413 &ProblemNumber,
2414 DeviceInfoData->DevInst,
2415 0,
2416 dap->hMachine);
2417 if (cr == CR_SUCCESS && (Status & DN_HAS_PROBLEM))
2418 {
2419 switch (ProblemNumber)
2420 {
2421 case CM_PROB_DEVLOADER_FAILED:
2422 {
2423 /* FIXME - only if it's not a root bus devloader,
2424 disable the button otherwise */
2425 TroubleShootStrId = IDS_UPDATEDRV;
2426 break;
2427 }
2428
2429 case CM_PROB_OUT_OF_MEMORY:
2430 case CM_PROB_ENTRY_IS_WRONG_TYPE:
2431 case CM_PROB_LACKED_ARBITRATOR:
2432 case CM_PROB_FAILED_START:
2433 case CM_PROB_LIAR:
2434 case CM_PROB_UNKNOWN_RESOURCE:
2435 {
2436 TroubleShootStrId = IDS_UPDATEDRV;
2437 break;
2438 }
2439
2440 case CM_PROB_BOOT_CONFIG_CONFLICT:
2441 case CM_PROB_NORMAL_CONFLICT:
2442 case CM_PROB_REENUMERATION:
2443 {
2444 /* FIXME - Troubleshoot conflict */
2445 break;
2446 }
2447
2448 case CM_PROB_FAILED_FILTER:
2449 case CM_PROB_REINSTALL:
2450 case CM_PROB_FAILED_INSTALL:
2451 {
2452 TroubleShootStrId = IDS_REINSTALLDRV;
2453 break;
2454 }
2455
2456 case CM_PROB_DEVLOADER_NOT_FOUND:
2457 {
2458 /* FIXME - 4 cases:
2459 1) if it's a missing system devloader:
2460 - disable the button (Reinstall Driver)
2461 2) if it's not a system devloader but still missing:
2462 - Reinstall Driver
2463 3) if it's not a system devloader but the file can be found:
2464 - Update Driver
2465 4) if it's a missing or empty software key
2466 - Update Driver
2467 */
2468 break;
2469 }
2470
2471 case CM_PROB_INVALID_DATA:
2472 case CM_PROB_PARTIAL_LOG_CONF:
2473 case CM_PROB_NO_VALID_LOG_CONF:
2474 case CM_PROB_HARDWARE_DISABLED:
2475 case CM_PROB_CANT_SHARE_IRQ:
2476 case CM_PROB_TRANSLATION_FAILED:
2477 case CM_PROB_SYSTEM_SHUTDOWN:
2478 case CM_PROB_PHANTOM:
2479 bDevActionAvailable = FALSE;
2480 break;
2481
2482 case CM_PROB_NOT_VERIFIED:
2483 case CM_PROB_DEVICE_NOT_THERE:
2484 /* FIXME - search hardware */
2485 break;
2486
2487 case CM_PROB_NEED_RESTART:
2488 case CM_PROB_WILL_BE_REMOVED:
2489 case CM_PROB_MOVED:
2490 case CM_PROB_TOO_EARLY:
2491 case CM_PROB_DISABLED_SERVICE:
2492 TroubleShootStrId = IDS_REBOOT;
2493 break;
2494
2495 case CM_PROB_REGISTRY:
2496 /* FIXME - check registry? */
2497 break;
2498
2499 case CM_PROB_DISABLED:
2500 /* if device was disabled by the user: */
2501 TroubleShootStrId = IDS_ENABLEDEV;
2502 /* FIXME - otherwise disable button because the device was
2503 disabled by the system*/
2504 break;
2505
2506 case CM_PROB_DEVLOADER_NOT_READY:
2507 /* FIXME - if it's a graphics adapter:
2508 - if it's a a secondary adapter and the main adapter
2509 couldn't be found
2510 - disable button
2511 - else
2512 - Properties
2513 - else
2514 - Update driver
2515 */
2516 break;
2517
2518 case CM_PROB_FAILED_ADD:
2519 TroubleShootStrId = IDS_PROPERTIES;
2520 break;
2521 }
2522 }
2523
2524 if (LoadString(hDllInstance,
2525 TroubleShootStrId,
2526 dap->szTemp,
2527 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])) != 0)
2528 {
2529 SetWindowText(hDevProbBtn,
2530 dap->szTemp);
2531 }
2532 EnableWindow(hDevProbBtn,
2533 dap->IsAdmin && bDevActionAvailable);
2534
2535 /* check if the device can be enabled/disabled */
2536 hDevUsage = GetDlgItem(hwndDlg,
2537 IDC_DEVUSAGE);
2538
2539 dap->CanDisable = FALSE;
2540 dap->DeviceStarted = FALSE;
2541
2542 if (CanDisableDevice(DeviceInfoData->DevInst,
2543 dap->hMachine,
2544 &bFlag))
2545 {
2546 dap->CanDisable = bFlag;
2547 }
2548
2549 if (IsDeviceStarted(DeviceInfoData->DevInst,
2550 dap->hMachine,
2551 &bFlag))
2552 {
2553 dap->DeviceStarted = bFlag;
2554 }
2555
2556 /* enable/disable the device usage controls */
2557 EnableWindow(GetDlgItem(hwndDlg,
2558 IDC_DEVUSAGELABEL),
2559 dap->CanDisable && dap->IsAdmin);
2560 EnableWindow(hDevUsage,
2561 dap->CanDisable && dap->IsAdmin);
2562
2563 /* clear the combobox */
2564 SendMessage(hDevUsage,
2565 CB_RESETCONTENT,
2566 0,
2567 0);
2568 if (dap->CanDisable)
2569 {
2570 InitDevUsageActions(hwndDlg,
2571 hDevUsage,
2572 dap);
2573 }
2574
2575 /* find out how many new device property sheets to add.
2576 fake a PROPSHEETHEADER structure, we don't plan to
2577 call PropertySheet again!*/
2578 psh.dwSize = sizeof(PROPSHEETHEADER);
2579 psh.dwFlags = 0;
2580 psh.nPages = 0;
2581
2582 /* get the number of device property sheets for the device */
2583 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet,
2584 DeviceInfoData,
2585 &psh,
2586 0,
2587 &nDriverPages,
2588 dap->PropertySheetType) &&
2589 nDriverPages != 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
2590 {
2591 dap->nDevPropSheets += nDriverPages;
2592 }
2593 else
2594 {
2595 nDriverPages = 0;
2596 }
2597
2598 dap->pResourceList = GetResourceList(dap->szDeviceID);
2599
2600 /* include the driver page */
2601 if (dap->HasDriverPage)
2602 dap->nDevPropSheets++;
2603
2604 /* include the details page */
2605 if (dap->Extended)
2606 dap->nDevPropSheets++;
2607
2608 if (dap->HasResourcePage && dap->pResourceList != NULL)
2609 dap->nDevPropSheets++;
2610
2611 /* add the device property sheets */
2612 if (dap->nDevPropSheets != 0)
2613 {
2614 dap->DevPropSheets = (HPROPSHEETPAGE *)HeapAlloc(GetProcessHeap(),
2615 HEAP_ZERO_MEMORY,
2616 dap->nDevPropSheets * sizeof(HPROPSHEETPAGE));
2617 if (dap->DevPropSheets != NULL)
2618 {
2619 if (nDriverPages != 0)
2620 {
2621 psh.phpage = dap->DevPropSheets;
2622
2623 /* query the device property sheet pages to add */
2624 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet,
2625 DeviceInfoData,
2626 &psh,
2627 dap->nDevPropSheets,
2628 NULL,
2629 dap->PropertySheetType))
2630 {
2631 /* add the property sheets */
2632 for (iPage = 0;
2633 iPage < nDriverPages;
2634 iPage++)
2635 {
2636 if (PropSheet_AddPage(hPropSheetDlg,
2637 dap->DevPropSheets[iPage]))
2638 {
2639 RecalcPages = TRUE;
2640 }
2641 }
2642
2643 dap->FreeDevPropSheets = TRUE;
2644 }
2645 else
2646 {
2647 /* cleanup, we were unable to get the device property sheets */
2648 iPage = nDriverPages;
2649 dap->nDevPropSheets -= nDriverPages;
2650 nDriverPages = 0;
2651 }
2652 }
2653 else
2654 iPage = 0;
2655
2656 /* add the driver page if necessary */
2657 if (dap->HasDriverPage)
2658 {
2659 PROPSHEETPAGE pspDriver = {0};
2660 pspDriver.dwSize = sizeof(PROPSHEETPAGE);
2661 pspDriver.dwFlags = PSP_DEFAULT;
2662 pspDriver.hInstance = hDllInstance;
2663 pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDRIVER);
2664 pspDriver.pfnDlgProc = AdvProcDriverDlgProc;
2665 pspDriver.lParam = (LPARAM)dap;
2666 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver);
2667 if (dap->DevPropSheets[iPage] != NULL)
2668 {
2669 if (PropSheet_AddPage(hPropSheetDlg,
2670 dap->DevPropSheets[iPage]))
2671 {
2672 iPage++;
2673 RecalcPages = TRUE;
2674 }
2675 else
2676 {
2677 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]);
2678 dap->DevPropSheets[iPage] = NULL;
2679 }
2680 }
2681 }
2682
2683 if (dap->Extended)
2684 {
2685 /* Add the details page */
2686 PROPSHEETPAGE pspDetails = {0};
2687 pspDetails.dwSize = sizeof(PROPSHEETPAGE);
2688 pspDetails.dwFlags = PSP_DEFAULT;
2689 pspDetails.hInstance = hDllInstance;
2690 pspDetails.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDETAILS);
2691 pspDetails.pfnDlgProc = AdvProcDetailsDlgProc;
2692 pspDetails.lParam = (LPARAM)dap;
2693 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDetails);
2694 if (dap->DevPropSheets[iPage] != NULL)
2695 {
2696 if (PropSheet_AddPage(hPropSheetDlg,
2697 dap->DevPropSheets[iPage]))
2698 {
2699 iPage++;
2700 RecalcPages = TRUE;
2701 }
2702 else
2703 {
2704 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]);
2705 dap->DevPropSheets[iPage] = NULL;
2706 }
2707 }
2708 }
2709
2710 if (dap->HasResourcePage && dap->pResourceList)
2711 {
2712 PROPSHEETPAGE pspDriver = {0};
2713 pspDriver.dwSize = sizeof(PROPSHEETPAGE);
2714 pspDriver.dwFlags = PSP_DEFAULT;
2715 pspDriver.hInstance = hDllInstance;
2716 pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICERESOURCES);
2717 pspDriver.pfnDlgProc = ResourcesProcDriverDlgProc;
2718 pspDriver.lParam = (LPARAM)dap;
2719 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver);
2720 if (dap->DevPropSheets[iPage] != NULL)
2721 {
2722 if (PropSheet_AddPage(hPropSheetDlg,
2723 dap->DevPropSheets[iPage]))
2724 {
2725 iPage++;
2726 RecalcPages = TRUE;
2727 }
2728 else
2729 {
2730 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]);
2731 dap->DevPropSheets[iPage] = NULL;
2732 }
2733 }
2734 }
2735 /* FIXME: Add the power page */
2736 }
2737 else
2738 dap->nDevPropSheets = 0;
2739 }
2740
2741 if (RecalcPages)
2742 {
2743 PropSheet_RecalcPageSizes(hPropSheetDlg);
2744 }
2745
2746 /* finally, disable the apply button */
2747 PropSheet_UnChanged(hPropSheetDlg,
2748 hwndDlg);
2749 dap->DeviceUsageChanged = FALSE;
2750 }
2751
2752
2753 static LRESULT
2754 CALLBACK
DlgParentSubWndProc(IN HWND hwnd,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)2755 DlgParentSubWndProc(IN HWND hwnd,
2756 IN UINT uMsg,
2757 IN WPARAM wParam,
2758 IN LPARAM lParam)
2759 {
2760 PDEVADVPROP_INFO dap;
2761
2762 dap = (PDEVADVPROP_INFO)GetProp(hwnd,
2763 L"DevMgrDevChangeSub");
2764 if (dap != NULL)
2765 {
2766 if (uMsg == WM_DEVICECHANGE && !IsWindowVisible(dap->hWndGeneralPage))
2767 {
2768 SendMessage(dap->hWndGeneralPage,
2769 WM_DEVICECHANGE,
2770 wParam,
2771 lParam);
2772 }
2773
2774 /* pass the message the the old window proc */
2775 return CallWindowProc(dap->ParentOldWndProc,
2776 hwnd,
2777 uMsg,
2778 wParam,
2779 lParam);
2780 }
2781 else
2782 {
2783 /* this is not a good idea if the subclassed window was an ansi
2784 window, but we failed finding out the previous window proc
2785 so we can't use CallWindowProc. This should rarely - if ever -
2786 happen. */
2787
2788 return DefWindowProc(hwnd,
2789 uMsg,
2790 wParam,
2791 lParam);
2792 }
2793 }
2794
2795
2796 static INT_PTR
2797 CALLBACK
AdvPropGeneralDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)2798 AdvPropGeneralDlgProc(IN HWND hwndDlg,
2799 IN UINT uMsg,
2800 IN WPARAM wParam,
2801 IN LPARAM lParam)
2802 {
2803 PDEVADVPROP_INFO dap;
2804 INT_PTR Ret = FALSE;
2805
2806 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER);
2807
2808 if (dap != NULL || uMsg == WM_INITDIALOG)
2809 {
2810 switch (uMsg)
2811 {
2812 case WM_COMMAND:
2813 {
2814 switch (LOWORD(wParam))
2815 {
2816 case IDC_DEVUSAGE:
2817 {
2818 if (HIWORD(wParam) == CBN_SELCHANGE)
2819 {
2820 PropSheet_Changed(GetParent(hwndDlg),
2821 hwndDlg);
2822 dap->DeviceUsageChanged = TRUE;
2823 }
2824 break;
2825 }
2826
2827 case IDC_DEVPROBLEM:
2828 {
2829 if (dap->IsAdmin)
2830 {
2831 /* display the device problem wizard */
2832 ShowDeviceProblemWizard(hwndDlg,
2833 dap->DeviceInfoSet,
2834 &dap->DeviceInfoData,
2835 dap->hMachine);
2836 }
2837 break;
2838 }
2839 }
2840 break;
2841 }
2842
2843 case WM_NOTIFY:
2844 {
2845 NMHDR *hdr = (NMHDR*)lParam;
2846 switch (hdr->code)
2847 {
2848 case PSN_APPLY:
2849 ApplyGeneralSettings(hwndDlg,
2850 dap);
2851 break;
2852 }
2853 break;
2854 }
2855
2856 case WM_INITDIALOG:
2857 {
2858 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
2859 if (dap != NULL)
2860 {
2861 HWND hWndParent;
2862
2863 dap->hWndGeneralPage = hwndDlg;
2864
2865 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap);
2866
2867 /* subclass the parent window to always receive
2868 WM_DEVICECHANGE messages */
2869 hWndParent = GetParent(hwndDlg);
2870 if (hWndParent != NULL)
2871 {
2872 /* subclass the parent window. This is not safe
2873 if the parent window belongs to another thread! */
2874 dap->ParentOldWndProc = (WNDPROC)SetWindowLongPtr(hWndParent,
2875 GWLP_WNDPROC,
2876 (LONG_PTR)DlgParentSubWndProc);
2877
2878 if (dap->ParentOldWndProc != NULL &&
2879 SetProp(hWndParent,
2880 L"DevMgrDevChangeSub",
2881 (HANDLE)dap))
2882 {
2883 dap->hWndParent = hWndParent;
2884 }
2885 }
2886
2887 /* do not call UpdateDevInfo directly in here because it modifies
2888 the pages of the property sheet! */
2889 PostMessage(hwndDlg,
2890 PM_INITIALIZE,
2891 0,
2892 0);
2893 }
2894 Ret = TRUE;
2895 break;
2896 }
2897
2898 case WM_DEVICECHANGE:
2899 {
2900 /* FIXME - don't call UpdateDevInfo for all events */
2901 UpdateDevInfo(hwndDlg,
2902 dap,
2903 TRUE);
2904 Ret = TRUE;
2905 break;
2906 }
2907
2908 case PM_INITIALIZE:
2909 {
2910 UpdateDevInfo(hwndDlg,
2911 dap,
2912 FALSE);
2913 dap->PageInitialized = TRUE;
2914 break;
2915 }
2916
2917 case WM_DESTROY:
2918 {
2919 /* restore the old window proc of the subclassed parent window */
2920 if (dap->hWndParent != NULL && dap->ParentOldWndProc != NULL)
2921 {
2922 if (SetWindowLongPtr(dap->hWndParent,
2923 GWLP_WNDPROC,
2924 (LONG_PTR)dap->ParentOldWndProc) == (LONG_PTR)DlgParentSubWndProc)
2925 {
2926 RemoveProp(dap->hWndParent,
2927 L"DevMgrDevChangeSub");
2928 }
2929 }
2930 break;
2931 }
2932 }
2933 }
2934
2935 return Ret;
2936 }
2937
2938
2939 INT_PTR
DisplayDeviceAdvancedProperties(IN HWND hWndParent,IN LPCWSTR lpDeviceID OPTIONAL,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData,IN HINSTANCE hComCtl32,IN LPCWSTR lpMachineName,IN DWORD dwFlags)2940 DisplayDeviceAdvancedProperties(IN HWND hWndParent,
2941 IN LPCWSTR lpDeviceID OPTIONAL,
2942 IN HDEVINFO DeviceInfoSet,
2943 IN PSP_DEVINFO_DATA DeviceInfoData,
2944 IN HINSTANCE hComCtl32,
2945 IN LPCWSTR lpMachineName,
2946 IN DWORD dwFlags)
2947 {
2948 PROPSHEETHEADER psh = {0};
2949 PROPSHEETPAGE pspGeneral = {0};
2950 PPROPERTYSHEETW pPropertySheetW;
2951 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW;
2952 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage;
2953 PDEVADVPROP_INFO DevAdvPropInfo;
2954 HMACHINE hMachine = NULL;
2955 DWORD DevIdSize = 0;
2956 INT_PTR Ret = -1;
2957
2958 /* we don't want to statically link against comctl32, so find the
2959 functions we need dynamically */
2960 pPropertySheetW =
2961 (PPROPERTYSHEETW)GetProcAddress(hComCtl32,
2962 "PropertySheetW");
2963 pCreatePropertySheetPageW =
2964 (PCREATEPROPERTYSHEETPAGEW)GetProcAddress(hComCtl32,
2965 "CreatePropertySheetPageW");
2966 pDestroyPropertySheetPage =
2967 (PDESTROYPROPERTYSHEETPAGE)GetProcAddress(hComCtl32,
2968 "DestroyPropertySheetPage");
2969 if (pPropertySheetW == NULL ||
2970 pCreatePropertySheetPageW == NULL ||
2971 pDestroyPropertySheetPage == NULL)
2972 {
2973 return -1;
2974 }
2975
2976 if (lpDeviceID == NULL)
2977 {
2978 /* find out how much size is needed for the device id */
2979 if (SetupDiGetDeviceInstanceId(DeviceInfoSet,
2980 DeviceInfoData,
2981 NULL,
2982 0,
2983 &DevIdSize))
2984 {
2985 ERR("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
2986 return -1;
2987 }
2988
2989 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
2990 {
2991 return -1;
2992 }
2993 }
2994 else
2995 {
2996 DevIdSize = (DWORD)wcslen(lpDeviceID) + 1;
2997 }
2998
2999 if (lpMachineName != NULL && lpMachineName[0] != L'\0')
3000 {
3001 CONFIGRET cr = CM_Connect_Machine(lpMachineName,
3002 &hMachine);
3003 if (cr != CR_SUCCESS)
3004 {
3005 return -1;
3006 }
3007 }
3008
3009 /* create the internal structure associated with the "General",
3010 "Driver", ... pages */
3011 DevAdvPropInfo = (PDEVADVPROP_INFO)HeapAlloc(GetProcessHeap(),
3012 HEAP_ZERO_MEMORY,
3013 FIELD_OFFSET(DEVADVPROP_INFO,
3014 szDeviceID) +
3015 (DevIdSize * sizeof(WCHAR)));
3016 if (DevAdvPropInfo == NULL)
3017 {
3018 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3019 goto Cleanup;
3020 }
3021
3022 if (lpDeviceID == NULL)
3023 {
3024 /* read the device instance id */
3025 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet,
3026 DeviceInfoData,
3027 DevAdvPropInfo->szDeviceID,
3028 DevIdSize,
3029 NULL))
3030 {
3031 goto Cleanup;
3032 }
3033 }
3034 else
3035 {
3036 /* copy the device instance id supplied by the caller */
3037 wcscpy(DevAdvPropInfo->szDeviceID,
3038 lpDeviceID);
3039 }
3040
3041 DevAdvPropInfo->DeviceInfoSet = DeviceInfoSet;
3042 DevAdvPropInfo->DeviceInfoData = *DeviceInfoData;
3043 DevAdvPropInfo->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE;
3044 DevAdvPropInfo->CurrentDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
3045
3046 DevAdvPropInfo->ShowRemotePages = (lpMachineName != NULL && lpMachineName[0] != L'\0');
3047 DevAdvPropInfo->hMachine = hMachine;
3048 DevAdvPropInfo->lpMachineName = lpMachineName;
3049 DevAdvPropInfo->szDevName[0] = L'\0';
3050 DevAdvPropInfo->hComCtl32 = hComCtl32;
3051 DevAdvPropInfo->pCreatePropertySheetPageW = pCreatePropertySheetPageW;
3052 DevAdvPropInfo->pDestroyPropertySheetPage = pDestroyPropertySheetPage;
3053
3054 DevAdvPropInfo->IsAdmin = TRUE;// IsUserAdmin();
3055 DevAdvPropInfo->DoDefaultDevAction = ((dwFlags & DPF_DEVICE_STATUS_ACTION) != 0);
3056 DevAdvPropInfo->Extended = ((dwFlags & DPF_EXTENDED) != 0);
3057
3058 psh.dwSize = sizeof(PROPSHEETHEADER);
3059 psh.dwFlags = PSH_PROPTITLE | PSH_NOAPPLYNOW;
3060 psh.hwndParent = hWndParent;
3061 psh.pszCaption = DevAdvPropInfo->szDevName;
3062
3063 DevAdvPropInfo->PropertySheetType = DevAdvPropInfo->ShowRemotePages ?
3064 DIGCDP_FLAG_REMOTE_ADVANCED :
3065 DIGCDP_FLAG_ADVANCED;
3066
3067 psh.phpage = (HPROPSHEETPAGE *)HeapAlloc(GetProcessHeap(),
3068 HEAP_ZERO_MEMORY,
3069 1 * sizeof(HPROPSHEETPAGE));
3070 if (psh.phpage == NULL)
3071 {
3072 goto Cleanup;
3073 }
3074
3075 /* add the "General" property sheet */
3076 pspGeneral.dwSize = sizeof(PROPSHEETPAGE);
3077 pspGeneral.dwFlags = PSP_DEFAULT;
3078 pspGeneral.hInstance = hDllInstance;
3079 pspGeneral.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEGENERAL);
3080 pspGeneral.pfnDlgProc = AdvPropGeneralDlgProc;
3081 pspGeneral.lParam = (LPARAM)DevAdvPropInfo;
3082 psh.phpage[psh.nPages] = pCreatePropertySheetPageW(&pspGeneral);
3083 if (psh.phpage[psh.nPages] != NULL)
3084 {
3085 psh.nPages++;
3086 }
3087
3088 DevAdvPropInfo->nDevPropSheets = psh.nPages;
3089
3090 if (psh.nPages != 0)
3091 {
3092 Ret = pPropertySheetW(&psh);
3093
3094 /* NOTE: no need to destroy the property sheets anymore! */
3095 }
3096 else
3097 {
3098 UINT i;
3099
3100 Cleanup:
3101 /* in case of failure the property sheets must be destroyed */
3102 if (psh.phpage != NULL)
3103 {
3104 for (i = 0;
3105 i < psh.nPages;
3106 i++)
3107 {
3108 if (psh.phpage[i] != NULL)
3109 {
3110 pDestroyPropertySheetPage(psh.phpage[i]);
3111 }
3112 }
3113 }
3114 }
3115
3116 if (Ret != 1)
3117 {
3118 SP_DEVINSTALL_PARAMS_W DeviceInstallParams;
3119
3120 DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
3121 if (SetupDiGetDeviceInstallParamsW(DeviceInfoSet,
3122 DeviceInfoData,
3123 &DeviceInstallParams))
3124 {
3125 SP_PROPCHANGE_PARAMS PropChangeParams;
3126 PropChangeParams.ClassInstallHeader.cbSize = sizeof(PropChangeParams.ClassInstallHeader);
3127 PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
3128 PropChangeParams.Scope = DICS_FLAG_GLOBAL;
3129 PropChangeParams.StateChange = DICS_PROPCHANGE;
3130
3131 SetupDiSetClassInstallParamsW(DeviceInfoSet,
3132 DeviceInfoData,
3133 (PSP_CLASSINSTALL_HEADER)&PropChangeParams,
3134 sizeof(PropChangeParams));
3135
3136 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
3137 DeviceInfoSet,
3138 DeviceInfoData);
3139
3140 DeviceInstallParams.FlagsEx &= ~DI_FLAGSEX_PROPCHANGE_PENDING;
3141 SetupDiSetDeviceInstallParamsW(DeviceInfoSet,
3142 DeviceInfoData,
3143 &DeviceInstallParams);
3144 }
3145 }
3146
3147 if (DevAdvPropInfo != NULL)
3148 {
3149 if (DevAdvPropInfo->FreeDevPropSheets)
3150 {
3151 /* don't free the array if it's the one allocated in
3152 DisplayDeviceAdvancedProperties */
3153 HeapFree(GetProcessHeap(),
3154 0,
3155 DevAdvPropInfo->DevPropSheets);
3156 }
3157
3158 if (DevAdvPropInfo->CloseDevInst)
3159 {
3160 /* close the device info set in case a new one was created */
3161 SetupDiDestroyDeviceInfoList(DevAdvPropInfo->DeviceInfoSet);
3162 }
3163
3164 if (DevAdvPropInfo->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
3165 {
3166 SetupDiDestroyDeviceInfoList(DevAdvPropInfo->CurrentDeviceInfoSet);
3167 }
3168
3169 if (DevAdvPropInfo->hDevIcon != NULL)
3170 {
3171 DestroyIcon(DevAdvPropInfo->hDevIcon);
3172 }
3173
3174 if (DevAdvPropInfo->pResourceList != NULL)
3175 HeapFree(GetProcessHeap(), 0, DevAdvPropInfo->pResourceList);
3176
3177 HeapFree(GetProcessHeap(),
3178 0,
3179 DevAdvPropInfo);
3180 }
3181
3182 if (psh.phpage != NULL)
3183 {
3184 HeapFree(GetProcessHeap(),
3185 0,
3186 psh.phpage);
3187 }
3188
3189 if (hMachine != NULL)
3190 {
3191 CM_Disconnect_Machine(hMachine);
3192 }
3193
3194 return Ret;
3195 }
3196