Reactos
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
46typedef 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
59static UINT WINAPI
60EnumDeviceDriverFilesCallback(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
80static VOID
81UpdateDriverDetailsDlg(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
185static VOID
186UpdateDriverVersionInfoDetails(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
261done:
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
303static INT_PTR
304CALLBACK
305DriverDetailsDlgProc(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
432static
433INT_PTR
434CALLBACK
435UninstallDriverDlgProc(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
494static
495VOID
496UninstallDriver(
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
530static
531VOID
532UpdateDriver(
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
595static VOID
596UpdateDriverDlg(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
676static INT_PTR
677CALLBACK
678AdvProcDriverDlgProc(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
751static VOID
752SetListViewText(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
769static VOID
770UpdateDetailsDlg(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
865static VOID
866DisplayDevicePropertyText(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
1027static VOID
1028DisplayDevNodeFlags(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
1113static VOID
1114DisplayDevNodeEnumerator(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
1144static VOID
1145DisplayCsFlags(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
1172static VOID
1173DisplayMatchingDeviceId(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
1218static VOID
1219DisplayClassCoinstallers(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
1299done:
1300 if (lpBuffer != NULL)
1301 HeapFree(GetProcessHeap(), 0, lpBuffer);
1302
1303 if (hKey != INVALID_HANDLE_VALUE)
1304 RegCloseKey(hKey);
1305}
1306
1307
1308static VOID
1309DisplayDeviceCoinstallers(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
1384static VOID
1385DisplayClassProperties(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
1478static VOID
1479DisplayDeviceRelations(
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
1529static VOID
1530DisplayCurrentPowerState(
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
1590static VOID
1591DisplayPowerCapabilities(
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
1651static VOID
1652DisplayPowerStateMappings(
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
1727static VOID
1728DisplayDeviceProperties(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
1884static INT_PTR
1885CALLBACK
1886AdvProcDetailsDlgProc(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
2018static VOID
2019InitDevUsageActions(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
2083static UINT
2084GetSelectedUsageAction(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
2109static BOOL
2110ApplyGeneralSettings(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
2176static VOID
2177UpdateDevInfo(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 {
2273GetParentNode:
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
2753static LRESULT
2754CALLBACK
2755DlgParentSubWndProc(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
2796static INT_PTR
2797CALLBACK
2798AdvPropGeneralDlgProc(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
2939INT_PTR
2940DisplayDeviceAdvancedProperties(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
3100Cleanup:
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}