Merge PR #283 "[USBPORT] Transaction Translator (TT) support bringup"
[reactos.git] / dll / win32 / devmgr / properties / advprop.cpp
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
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
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
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
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 MAX_PATH);
417
418 UpdateDriverVersionInfoDetails(hwndDlg,
419 szDriverPath);
420 }
421 }
422 }
423 break;
424 }
425 }
426 }
427
428 return Ret;
429 }
430
431
432 static
433 VOID
434 UpdateDriver(
435 IN HWND hwndDlg,
436 IN PDEVADVPROP_INFO dap)
437 {
438 TOKEN_PRIVILEGES Privileges;
439 HANDLE hToken;
440 DWORD dwReboot;
441 BOOL NeedReboot = FALSE;
442
443 // Better use InstallDevInst:
444 // BOOL
445 // WINAPI
446 // InstallDevInst(
447 // HWND hWnd,
448 // LPWSTR wszDeviceId,
449 // BOOL bUpdate,
450 // DWORD *dwReboot);
451 // See: http://comp.os.ms-windows.programmer.win32.narkive.com/J8FTd4KK/signature-of-undocumented-installdevinstex
452
453 if (!InstallDevInst(hwndDlg, dap->szDeviceID, TRUE, &dwReboot))
454 return;
455
456 if (NeedReboot == FALSE)
457 return;
458
459 //FIXME: load text from resource file
460 if (MessageBoxW(hwndDlg, L"Reboot now?", L"Reboot required", MB_YESNO | MB_ICONQUESTION) != IDYES)
461 return;
462
463 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
464 {
465 ERR("OpenProcessToken failed\n");
466 return;
467 }
468
469 /* Get the LUID for the Shutdown privilege */
470 if (!LookupPrivilegeValueW(NULL, SE_SHUTDOWN_NAME, &Privileges.Privileges[0].Luid))
471 {
472 ERR("LookupPrivilegeValue failed\n");
473 CloseHandle(hToken);
474 return;
475 }
476
477 /* Assign the Shutdown privilege to our process */
478 Privileges.PrivilegeCount = 1;
479 Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
480
481 if (!AdjustTokenPrivileges(hToken, FALSE, &Privileges, 0, NULL, NULL))
482 {
483 ERR("AdjustTokenPrivileges failed\n");
484 CloseHandle(hToken);
485 return;
486 }
487
488 /* Finally shut down the system */
489 if (!ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED))
490 {
491 ERR("ExitWindowsEx failed\n");
492 CloseHandle(hToken);
493 }
494 }
495
496
497 static VOID
498 UpdateDriverDlg(IN HWND hwndDlg,
499 IN PDEVADVPROP_INFO dap)
500 {
501 HDEVINFO DeviceInfoSet;
502 PSP_DEVINFO_DATA DeviceInfoData;
503
504 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
505 {
506 DeviceInfoSet = dap->CurrentDeviceInfoSet;
507 DeviceInfoData = &dap->CurrentDeviceInfoData;
508 }
509 else
510 {
511 DeviceInfoSet = dap->DeviceInfoSet;
512 DeviceInfoData = &dap->DeviceInfoData;
513 }
514
515 /* set the device image */
516 SendDlgItemMessage(hwndDlg,
517 IDC_DEVICON,
518 STM_SETICON,
519 (WPARAM)dap->hDevIcon,
520 0);
521
522 /* set the device name edit control text */
523 SetDlgItemText(hwndDlg,
524 IDC_DEVNAME,
525 dap->szDevName);
526
527 /* query the driver provider */
528 if (GetDriverProviderString(DeviceInfoSet,
529 DeviceInfoData,
530 dap->szTemp,
531 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
532 {
533 SetDlgItemText(hwndDlg,
534 IDC_DRVPROVIDER,
535 dap->szTemp);
536 }
537
538 /* query the driver date */
539 if (GetDriverDateString(DeviceInfoSet,
540 DeviceInfoData,
541 dap->szTemp,
542 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
543 {
544 SetDlgItemText(hwndDlg,
545 IDC_DRVDATE,
546 dap->szTemp);
547 }
548
549 /* query the driver version */
550 if (GetDriverVersionString(DeviceInfoSet,
551 DeviceInfoData,
552 dap->szTemp,
553 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
554 {
555 SetDlgItemText(hwndDlg,
556 IDC_DRVVERSION,
557 dap->szTemp);
558 }
559 }
560
561
562 static INT_PTR
563 CALLBACK
564 AdvProcDriverDlgProc(IN HWND hwndDlg,
565 IN UINT uMsg,
566 IN WPARAM wParam,
567 IN LPARAM lParam)
568 {
569 PDEVADVPROP_INFO dap;
570 INT_PTR Ret = FALSE;
571
572 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER);
573
574 if (dap != NULL || uMsg == WM_INITDIALOG)
575 {
576 switch (uMsg)
577 {
578 case WM_COMMAND:
579 {
580 switch (LOWORD(wParam))
581 {
582 case IDC_DRIVERDETAILS:
583 DialogBoxParam(hDllInstance,
584 MAKEINTRESOURCE(IDD_DRIVERDETAILS),
585 hwndDlg,
586 DriverDetailsDlgProc,
587 (ULONG_PTR)dap);
588 break;
589
590 case IDC_UPDATEDRIVER:
591 UpdateDriver(hwndDlg, dap);
592 break;
593
594 case IDC_ROLLBACKDRIVER:
595 // FIXME
596 break;
597
598 case IDC_UNINSTALLDRIVER:
599 // FIXME
600 break;
601 }
602 break;
603 }
604
605 case WM_NOTIFY:
606 {
607 NMHDR *hdr = (NMHDR*)lParam;
608 switch (hdr->code)
609 {
610 case PSN_APPLY:
611 break;
612 }
613 break;
614 }
615
616 case WM_INITDIALOG:
617 {
618 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
619 if (dap != NULL)
620 {
621 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap);
622
623 UpdateDriverDlg(hwndDlg,
624 dap);
625 }
626 EnableWindow(GetDlgItem(hwndDlg, IDC_ROLLBACKDRIVER), FALSE);
627 EnableWindow(GetDlgItem(hwndDlg, IDC_UNINSTALLDRIVER), FALSE);
628 Ret = TRUE;
629 break;
630 }
631 }
632 }
633
634 return Ret;
635 }
636
637
638 static VOID
639 SetListViewText(HWND hwnd,
640 INT iItem,
641 LPCWSTR lpText)
642 {
643 LVITEM li;
644
645 li.mask = LVIF_TEXT | LVIF_STATE;
646 li.iItem = iItem;
647 li.iSubItem = 0;
648 li.state = 0; //(li.iItem == 0 ? LVIS_SELECTED : 0);
649 li.stateMask = LVIS_SELECTED;
650 li.pszText = (LPWSTR)lpText;
651 (void)ListView_InsertItem(hwnd,
652 &li);
653 }
654
655
656 static VOID
657 UpdateDetailsDlg(IN HWND hwndDlg,
658 IN PDEVADVPROP_INFO dap)
659 {
660 HWND hwndComboBox;
661 HWND hwndListView;
662 LV_COLUMN lvc;
663 RECT rcClient;
664
665 UINT i;
666 UINT Properties[] =
667 {
668 IDS_PROP_DEVICEID,
669 IDS_PROP_HARDWAREIDS,
670 IDS_PROP_COMPATIBLEIDS,
671 IDS_PROP_MATCHINGDEVICEID,
672 IDS_PROP_SERVICE,
673 IDS_PROP_ENUMERATOR,
674 IDS_PROP_CAPABILITIES,
675 IDS_PROP_DEVNODEFLAGS,
676 IDS_PROP_CONFIGFLAGS,
677 IDS_PROP_CSCONFIGFLAGS,
678 IDS_PROP_EJECTIONRELATIONS,
679 IDS_PROP_REMOVALRELATIONS,
680 IDS_PROP_BUSRELATIONS,
681 IDS_PROP_DEVUPPERFILTERS,
682 IDS_PROP_DEVLOWERFILTERS,
683 IDS_PROP_CLASSUPPERFILTERS,
684 IDS_PROP_CLASSLOWERFILTERS,
685 IDS_PROP_CLASSINSTALLER,
686 IDS_PROP_CLASSCOINSTALLER,
687 IDS_PROP_DEVICECOINSTALLER,
688 IDS_PROP_FIRMWAREREVISION,
689 IDS_PROP_CURRENTPOWERSTATE,
690 IDS_PROP_POWERCAPABILITIES,
691 IDS_PROP_POWERSTATEMAPPINGS
692 };
693
694
695 /* set the device image */
696 SendDlgItemMessage(hwndDlg,
697 IDC_DEVICON,
698 STM_SETICON,
699 (WPARAM)dap->hDevIcon,
700 0);
701
702 /* set the device name edit control text */
703 SetDlgItemText(hwndDlg,
704 IDC_DEVNAME,
705 dap->szDevName);
706
707
708 hwndComboBox = GetDlgItem(hwndDlg,
709 IDC_DETAILSPROPNAME);
710
711 hwndListView = GetDlgItem(hwndDlg,
712 IDC_DETAILSPROPVALUE);
713
714 for (i = 0; i != sizeof(Properties) / sizeof(Properties[0]); i++)
715 {
716 /* fill in the device usage combo box */
717 if (LoadString(hDllInstance,
718 Properties[i],
719 dap->szTemp,
720 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
721 {
722 SendMessage(hwndComboBox,
723 CB_ADDSTRING,
724 0,
725 (LPARAM)dap->szTemp);
726 }
727 }
728
729
730 GetClientRect(hwndListView,
731 &rcClient);
732
733 /* add a column to the list view control */
734 lvc.mask = LVCF_FMT | LVCF_WIDTH;
735 lvc.fmt = LVCFMT_LEFT;
736 lvc.cx = rcClient.right;
737 (void)ListView_InsertColumn(hwndListView,
738 0,
739 &lvc);
740
741 SendMessage(hwndComboBox,
742 CB_SETCURSEL,
743 0,
744 0);
745
746 SetListViewText(hwndListView, 0, dap->szDeviceID);
747
748 SetFocus(hwndComboBox);
749 }
750
751
752 static VOID
753 DisplayDevicePropertyText(IN PDEVADVPROP_INFO dap,
754 IN HWND hwndListView,
755 IN DWORD dwProperty)
756 {
757 HDEVINFO DeviceInfoSet;
758 PSP_DEVINFO_DATA DeviceInfoData;
759 DWORD dwType;
760 DWORD dwSize;
761 DWORD dwValue;
762 LPBYTE lpBuffer;
763 LPWSTR lpStr;
764 INT len;
765 INT index;
766
767 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
768 {
769 DeviceInfoSet = dap->CurrentDeviceInfoSet;
770 DeviceInfoData = &dap->CurrentDeviceInfoData;
771 }
772 else
773 {
774 DeviceInfoSet = dap->DeviceInfoSet;
775 DeviceInfoData = &dap->DeviceInfoData;
776 }
777
778 dwSize = 0;
779 SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
780 DeviceInfoData,
781 dwProperty,
782 &dwType,
783 NULL,
784 0,
785 &dwSize);
786 if (dwSize == 0)
787 {
788 if (GetLastError() != ERROR_FILE_NOT_FOUND)
789 {
790 swprintf(dap->szTemp, L"Error: Getting the size failed! (Error: %ld)", GetLastError());
791 SetListViewText(hwndListView, 0, dap->szTemp);
792 }
793 return;
794 }
795
796 if (dwType == REG_SZ)
797 dwSize += sizeof(WCHAR);
798
799 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(),
800 HEAP_ZERO_MEMORY,
801 dwSize);
802 if (lpBuffer == NULL)
803 {
804 SetListViewText(hwndListView, 0, L"Error: Allocating the buffer failed!");
805 return;
806 }
807
808 if (SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
809 DeviceInfoData,
810 dwProperty,
811 &dwType,
812 lpBuffer,
813 dwSize,
814 &dwSize))
815 {
816 if (dwType == REG_SZ)
817 {
818 SetListViewText(hwndListView, 0, (LPWSTR)lpBuffer);
819 }
820 else if (dwType == REG_MULTI_SZ)
821 {
822 lpStr = (LPWSTR)lpBuffer;
823 index = 0;
824 while (*lpStr != 0)
825 {
826 len = wcslen(lpStr) + 1;
827
828 SetListViewText(hwndListView, index, lpStr);
829
830 lpStr += len;
831 index++;
832 }
833 }
834 else if (dwType == REG_DWORD)
835 {
836 dwValue = *(DWORD *) lpBuffer;
837
838 switch (dwProperty)
839 {
840 case SPDRP_CAPABILITIES:
841 index = 0;
842 if (dwValue & CM_DEVCAP_LOCKSUPPORTED)
843 SetListViewText(hwndListView, index++, L"CM_DEVCAP_LOCKSUPPORTED");
844 if (dwValue & CM_DEVCAP_EJECTSUPPORTED)
845 SetListViewText(hwndListView, index++, L"CM_DEVCAP_EJECTSUPPORTED");
846 if (dwValue & CM_DEVCAP_REMOVABLE)
847 SetListViewText(hwndListView, index++, L"CM_DEVCAP_REMOVABLE");
848 if (dwValue & CM_DEVCAP_DOCKDEVICE)
849 SetListViewText(hwndListView, index++, L"CM_DEVCAP_DOCKDEVICE");
850 if (dwValue & CM_DEVCAP_UNIQUEID)
851 SetListViewText(hwndListView, index++, L"CM_DEVCAP_UNIQUEID");
852 if (dwValue & CM_DEVCAP_SILENTINSTALL)
853 SetListViewText(hwndListView, index++, L"CM_DEVCAP_SILENTINSTALL");
854 if (dwValue & CM_DEVCAP_RAWDEVICEOK)
855 SetListViewText(hwndListView, index++, L"CM_DEVCAP_RAWDEVICEOK");
856 if (dwValue & CM_DEVCAP_SURPRISEREMOVALOK)
857 SetListViewText(hwndListView, index++, L"CM_DEVCAP_SURPRISEREMOVALOK");
858 if (dwValue & CM_DEVCAP_HARDWAREDISABLED)
859 SetListViewText(hwndListView, index++, L"CM_DEVCAP_HARDWAREDISABLED");
860 if (dwValue & CM_DEVCAP_NONDYNAMIC)
861 SetListViewText(hwndListView, index++, L"CM_DEVCAP_NONDYNAMIC");
862 break;
863
864 case SPDRP_CONFIGFLAGS:
865 index = 0;
866 if (dwValue & CONFIGFLAG_DISABLED)
867 SetListViewText(hwndListView, index++, L"CONFIGFLAG_DISABLED");
868 if (dwValue & CONFIGFLAG_REMOVED)
869 SetListViewText(hwndListView, index++, L"CONFIGFLAG_REMOVED");
870 if (dwValue & CONFIGFLAG_MANUAL_INSTALL)
871 SetListViewText(hwndListView, index++, L"CONFIGFLAG_MANUAL_INSTALL");
872 if (dwValue & CONFIGFLAG_IGNORE_BOOT_LC)
873 SetListViewText(hwndListView, index++, L"CONFIGFLAG_IGNORE_BOOT_LC");
874 if (dwValue & CONFIGFLAG_NET_BOOT)
875 SetListViewText(hwndListView, index++, L"CONFIGFLAG_NET_BOOT");
876 if (dwValue & CONFIGFLAG_REINSTALL)
877 SetListViewText(hwndListView, index++, L"CONFIGFLAG_REINSTALL");
878 if (dwValue & CONFIGFLAG_FAILEDINSTALL)
879 SetListViewText(hwndListView, index++, L"CONFIGFLAG_FAILEDINSTALL");
880 if (dwValue & CONFIGFLAG_CANTSTOPACHILD)
881 SetListViewText(hwndListView, index++, L"CONFIGFLAG_CANTSTOPACHILD");
882 if (dwValue & CONFIGFLAG_OKREMOVEROM)
883 SetListViewText(hwndListView, index++, L"CONFIGFLAG_OKREMOVEROM");
884 if (dwValue & CONFIGFLAG_NOREMOVEEXIT)
885 SetListViewText(hwndListView, index++, L"CONFIGFLAG_NOREMOVEEXIT");
886 break;
887
888 default:
889 swprintf(dap->szTemp, L"0x%08lx", dwValue);
890 SetListViewText(hwndListView, 0, dap->szTemp);
891 break;
892 }
893 }
894 else
895 {
896 SetListViewText(hwndListView, 0, L"Error: Unsupported value type!");
897
898 }
899 }
900 else
901 {
902 SetListViewText(hwndListView, 0, L"Error: Retrieving the value failed!");
903 }
904
905 HeapFree(GetProcessHeap(),
906 0,
907 lpBuffer);
908 }
909
910 static VOID
911 DisplayDevNodeFlags(IN PDEVADVPROP_INFO dap,
912 IN HWND hwndListView)
913 {
914 DWORD dwStatus = 0;
915 DWORD dwProblem = 0;
916 INT index;
917
918 CM_Get_DevNode_Status_Ex(&dwStatus,
919 &dwProblem,
920 dap->DeviceInfoData.DevInst,
921 0,
922 dap->hMachine);
923
924 index = 0;
925 if (dwStatus & DN_ROOT_ENUMERATED)
926 SetListViewText(hwndListView, index++, L"DN_ROOT_ENUMERATED");
927 if (dwStatus & DN_DRIVER_LOADED)
928 SetListViewText(hwndListView, index++, L"DN_DRIVER_LOADED");
929 if (dwStatus & DN_ENUM_LOADED)
930 SetListViewText(hwndListView, index++, L"DN_ENUM_LOADED");
931 if (dwStatus & DN_STARTED)
932 SetListViewText(hwndListView, index++, L"DN_STARTED");
933 if (dwStatus & DN_MANUAL)
934 SetListViewText(hwndListView, index++, L"DN_MANUAL");
935 if (dwStatus & DN_NEED_TO_ENUM)
936 SetListViewText(hwndListView, index++, L"DN_NEED_TO_ENUM");
937 if (dwStatus & DN_DRIVER_BLOCKED)
938 SetListViewText(hwndListView, index++, L"DN_DRIVER_BLOCKED");
939 if (dwStatus & DN_HARDWARE_ENUM)
940 SetListViewText(hwndListView, index++, L"DN_HARDWARE_ENUM");
941 if (dwStatus & DN_NEED_RESTART)
942 SetListViewText(hwndListView, index++, L"DN_NEED_RESTART");
943 if (dwStatus & DN_CHILD_WITH_INVALID_ID)
944 SetListViewText(hwndListView, index++, L"DN_CHILD_WITH_INVALID_ID");
945 if (dwStatus & DN_HAS_PROBLEM)
946 SetListViewText(hwndListView, index++, L"DN_HAS_PROBLEM");
947 if (dwStatus & DN_FILTERED)
948 SetListViewText(hwndListView, index++, L"DN_FILTERED");
949 if (dwStatus & DN_LEGACY_DRIVER)
950 SetListViewText(hwndListView, index++, L"DN_LEGACY_DRIVER");
951 if (dwStatus & DN_DISABLEABLE)
952 SetListViewText(hwndListView, index++, L"DN_DISABLEABLE");
953 if (dwStatus & DN_REMOVABLE)
954 SetListViewText(hwndListView, index++, L"DN_REMOVABLE");
955 if (dwStatus & DN_PRIVATE_PROBLEM)
956 SetListViewText(hwndListView, index++, L"DN_PRIVATE_PROBLEM");
957 if (dwStatus & DN_MF_PARENT)
958 SetListViewText(hwndListView, index++, L"DN_MF_PARENT");
959 if (dwStatus & DN_MF_CHILD)
960 SetListViewText(hwndListView, index++, L"DN_MF_CHILD");
961 if (dwStatus & DN_WILL_BE_REMOVED)
962 SetListViewText(hwndListView, index++, L"DN_WILL_BE_REMOVED");
963
964 if (dwStatus & DN_NOT_FIRST_TIMEE)
965 SetListViewText(hwndListView, index++, L"DN_NOT_FIRST_TIMEE");
966 if (dwStatus & DN_STOP_FREE_RES)
967 SetListViewText(hwndListView, index++, L"DN_STOP_FREE_RES");
968 if (dwStatus & DN_REBAL_CANDIDATE)
969 SetListViewText(hwndListView, index++, L"DN_REBAL_CANDIDATE");
970 if (dwStatus & DN_BAD_PARTIAL)
971 SetListViewText(hwndListView, index++, L"DN_BAD_PARTIAL");
972 if (dwStatus & DN_NT_ENUMERATOR)
973 SetListViewText(hwndListView, index++, L"DN_NT_ENUMERATOR");
974 if (dwStatus & DN_NT_DRIVER)
975 SetListViewText(hwndListView, index++, L"DN_NT_DRIVER");
976
977 if (dwStatus & DN_NEEDS_LOCKING)
978 SetListViewText(hwndListView, index++, L"DN_NEEDS_LOCKING");
979 if (dwStatus & DN_ARM_WAKEUP)
980 SetListViewText(hwndListView, index++, L"DN_ARM_WAKEUP");
981 if (dwStatus & DN_APM_ENUMERATOR)
982 SetListViewText(hwndListView, index++, L"DN_APM_ENUMERATOR");
983 if (dwStatus & DN_APM_DRIVER)
984 SetListViewText(hwndListView, index++, L"DN_APM_DRIVER");
985 if (dwStatus & DN_SILENT_INSTALL)
986 SetListViewText(hwndListView, index++, L"DN_SILENT_INSTALL");
987 if (dwStatus & DN_NO_SHOW_IN_DM)
988 SetListViewText(hwndListView, index++, L"DN_NO_SHOW_IN_DM");
989 if (dwStatus & DN_BOOT_LOG_PROB)
990 SetListViewText(hwndListView, index++, L"DN_BOOT_LOG_PROB");
991
992 // swprintf(dap->szTemp, L"0x%08x", dwStatus);
993 // SetListViewText(hwndListView, 0, dap->szTemp);
994 }
995
996
997 static VOID
998 DisplayDevNodeEnumerator(IN PDEVADVPROP_INFO dap,
999 IN HWND hwndListView)
1000 {
1001 PSP_DEVINFO_DATA DeviceInfoData;
1002
1003 DWORD dwType = 0;
1004 WCHAR szBuffer[256];
1005 DWORD dwSize = 256 * sizeof(WCHAR);
1006
1007 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1008 {
1009 DeviceInfoData = &dap->CurrentDeviceInfoData;
1010 }
1011 else
1012 {
1013 DeviceInfoData = &dap->DeviceInfoData;
1014 }
1015
1016 CM_Get_DevNode_Registry_Property_ExW(DeviceInfoData->DevInst,
1017 CM_DRP_ENUMERATOR_NAME,
1018 &dwType,
1019 &szBuffer,
1020 &dwSize,
1021 0,
1022 dap->hMachine);
1023
1024 SetListViewText(hwndListView, 0, szBuffer);
1025 }
1026
1027
1028 static VOID
1029 DisplayCsFlags(IN PDEVADVPROP_INFO dap,
1030 IN HWND hwndListView)
1031 {
1032 DWORD dwValue = 0;
1033 INT index;
1034
1035 CM_Get_HW_Prof_Flags_Ex(dap->szDevName,
1036 0, /* current hardware profile */
1037 &dwValue,
1038 0,
1039 dap->hMachine);
1040
1041 index = 0;
1042 if (dwValue & CSCONFIGFLAG_DISABLED)
1043 SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DISABLED");
1044
1045 if (dwValue & CSCONFIGFLAG_DO_NOT_CREATE)
1046 SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DO_NOT_CREATE");
1047
1048 if (dwValue & CSCONFIGFLAG_DO_NOT_START)
1049 SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DO_NOT_START");
1050 }
1051
1052
1053 static VOID
1054 DisplayMatchingDeviceId(IN PDEVADVPROP_INFO dap,
1055 IN HWND hwndListView)
1056 {
1057 HDEVINFO DeviceInfoSet;
1058 PSP_DEVINFO_DATA DeviceInfoData;
1059 WCHAR szBuffer[256];
1060 HKEY hKey;
1061 DWORD dwSize;
1062 DWORD dwType;
1063
1064 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1065 {
1066 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1067 DeviceInfoData = &dap->CurrentDeviceInfoData;
1068 }
1069 else
1070 {
1071 DeviceInfoSet = dap->DeviceInfoSet;
1072 DeviceInfoData = &dap->DeviceInfoData;
1073 }
1074
1075 hKey = SetupDiOpenDevRegKey(DeviceInfoSet,
1076 DeviceInfoData,
1077 DICS_FLAG_GLOBAL,
1078 0,
1079 DIREG_DRV,
1080 KEY_QUERY_VALUE);
1081 if (hKey != INVALID_HANDLE_VALUE)
1082 {
1083 dwSize = 256 * sizeof(WCHAR);
1084 if (RegQueryValueEx(hKey,
1085 L"MatchingDeviceId",
1086 NULL,
1087 &dwType,
1088 (LPBYTE)szBuffer,
1089 &dwSize) == ERROR_SUCCESS)
1090 {
1091 SetListViewText(hwndListView, 0, szBuffer);
1092 }
1093
1094 RegCloseKey(hKey);
1095 }
1096 }
1097
1098
1099 static VOID
1100 DisplayClassCoinstallers(IN PDEVADVPROP_INFO dap,
1101 IN HWND hwndListView)
1102 {
1103 HDEVINFO DeviceInfoSet;
1104 PSP_DEVINFO_DATA DeviceInfoData;
1105 WCHAR szClassGuid[45];
1106 HKEY hKey = (HKEY)INVALID_HANDLE_VALUE;
1107 DWORD dwSize;
1108 DWORD dwType;
1109 LPBYTE lpBuffer = NULL;
1110 LPWSTR lpStr;
1111 INT index;
1112 INT len;
1113 LONG lError;
1114
1115 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1116 {
1117 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1118 DeviceInfoData = &dap->CurrentDeviceInfoData;
1119 }
1120 else
1121 {
1122 DeviceInfoSet = dap->DeviceInfoSet;
1123 DeviceInfoData = &dap->DeviceInfoData;
1124 }
1125
1126 dwSize = 45 * sizeof(WCHAR);
1127 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
1128 DeviceInfoData,
1129 SPDRP_CLASSGUID,
1130 &dwType,
1131 (LPBYTE)szClassGuid,
1132 dwSize,
1133 &dwSize))
1134 return;
1135
1136 lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1137 L"SYSTEM\\CurrentControlSet\\Control\\CoDeviceInstallers",
1138 0,
1139 GENERIC_READ,
1140 &hKey);
1141 if (lError != ERROR_SUCCESS)
1142 return;
1143
1144 dwSize = 0;
1145 lError = RegQueryValueEx(hKey,
1146 szClassGuid,
1147 NULL,
1148 &dwType,
1149 NULL,
1150 &dwSize);
1151 if (lError != ERROR_SUCCESS)
1152 goto done;
1153
1154 if (dwSize == 0)
1155 goto done;
1156
1157 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(),
1158 HEAP_ZERO_MEMORY,
1159 dwSize);
1160
1161 RegQueryValueEx(hKey,
1162 szClassGuid,
1163 NULL,
1164 &dwType,
1165 lpBuffer,
1166 &dwSize);
1167
1168 lpStr = (LPWSTR)lpBuffer;
1169 index = 0;
1170 while (*lpStr != 0)
1171 {
1172 len = wcslen(lpStr) + 1;
1173
1174 SetListViewText(hwndListView, index, lpStr);
1175
1176 lpStr += len;
1177 index++;
1178 }
1179
1180 done:
1181 if (lpBuffer != NULL)
1182 HeapFree(GetProcessHeap(), 0, lpBuffer);
1183
1184 if (hKey != INVALID_HANDLE_VALUE)
1185 RegCloseKey(hKey);
1186 }
1187
1188
1189 static VOID
1190 DisplayDeviceCoinstallers(IN PDEVADVPROP_INFO dap,
1191 IN HWND hwndListView)
1192 {
1193 HDEVINFO DeviceInfoSet;
1194 PSP_DEVINFO_DATA DeviceInfoData;
1195 HKEY hKey;
1196 DWORD dwSize;
1197 DWORD dwType;
1198 LPBYTE lpBuffer;
1199 LPWSTR lpStr;
1200 INT index;
1201 INT len;
1202
1203 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1204 {
1205 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1206 DeviceInfoData = &dap->CurrentDeviceInfoData;
1207 }
1208 else
1209 {
1210 DeviceInfoSet = dap->DeviceInfoSet;
1211 DeviceInfoData = &dap->DeviceInfoData;
1212 }
1213
1214 hKey = SetupDiOpenDevRegKey(DeviceInfoSet,
1215 DeviceInfoData,
1216 DICS_FLAG_GLOBAL,
1217 0,
1218 DIREG_DRV,
1219 KEY_QUERY_VALUE);
1220 if (hKey != INVALID_HANDLE_VALUE)
1221 {
1222 dwSize = 0;
1223 if (RegQueryValueEx(hKey,
1224 L"CoInstallers32",
1225 NULL,
1226 &dwType,
1227 NULL,
1228 &dwSize) == ERROR_SUCCESS &&
1229 dwSize > 0)
1230 {
1231
1232 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(),
1233 HEAP_ZERO_MEMORY,
1234 dwSize);
1235
1236 RegQueryValueEx(hKey,
1237 L"CoInstallers32",
1238 NULL,
1239 &dwType,
1240 lpBuffer,
1241 &dwSize);
1242
1243 lpStr = (LPWSTR)lpBuffer;
1244 index = 0;
1245 while (*lpStr != 0)
1246 {
1247 len = wcslen(lpStr) + 1;
1248
1249 SetListViewText(hwndListView, index, lpStr);
1250
1251 lpStr += len;
1252 index++;
1253 }
1254
1255 HeapFree(GetProcessHeap(),
1256 0,
1257 lpBuffer);
1258 }
1259
1260 RegCloseKey(hKey);
1261 }
1262 }
1263
1264
1265 static VOID
1266 DisplayClassProperties(IN PDEVADVPROP_INFO dap,
1267 IN HWND hwndListView,
1268 IN LPCWSTR lpProperty)
1269 {
1270 HDEVINFO DeviceInfoSet;
1271 PSP_DEVINFO_DATA DeviceInfoData;
1272 WCHAR szClassGuid[45];
1273 DWORD dwSize;
1274 DWORD dwType;
1275 HKEY hKey;
1276 GUID ClassGuid;
1277 LPBYTE lpBuffer;
1278 LPWSTR lpStr;
1279 INT index = 0;
1280 INT len;
1281
1282 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1283 {
1284 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1285 DeviceInfoData = &dap->CurrentDeviceInfoData;
1286 }
1287 else
1288 {
1289 DeviceInfoSet = dap->DeviceInfoSet;
1290 DeviceInfoData = &dap->DeviceInfoData;
1291 }
1292
1293 dwSize = 45 * sizeof(WCHAR);
1294 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
1295 DeviceInfoData,
1296 SPDRP_CLASSGUID,
1297 &dwType,
1298 (LPBYTE)szClassGuid,
1299 dwSize,
1300 &dwSize))
1301 return;
1302
1303 pSetupGuidFromString(szClassGuid,
1304 &ClassGuid);
1305
1306 hKey = SetupDiOpenClassRegKey(&ClassGuid,
1307 KEY_QUERY_VALUE);
1308 if (hKey != INVALID_HANDLE_VALUE)
1309 {
1310 dwSize = 0;
1311 if (RegQueryValueEx(hKey,
1312 lpProperty,
1313 NULL,
1314 &dwType,
1315 NULL,
1316 &dwSize) == ERROR_SUCCESS &&
1317 dwSize > 0)
1318 {
1319 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(),
1320 HEAP_ZERO_MEMORY,
1321 dwSize);
1322
1323 RegQueryValueEx(hKey,
1324 lpProperty,
1325 NULL,
1326 &dwType,
1327 lpBuffer,
1328 &dwSize);
1329
1330 if (dwType == REG_SZ)
1331 {
1332 SetListViewText(hwndListView, 0, (LPWSTR)lpBuffer);
1333 }
1334 else if (dwType == REG_MULTI_SZ)
1335 {
1336 lpStr = (LPWSTR)lpBuffer;
1337 index = 0;
1338 while (*lpStr != 0)
1339 {
1340 len = wcslen(lpStr) + 1;
1341
1342 SetListViewText(hwndListView, index, lpStr);
1343
1344 lpStr += len;
1345 index++;
1346 }
1347 }
1348
1349 HeapFree(GetProcessHeap(),
1350 0,
1351 lpBuffer);
1352 }
1353
1354 RegCloseKey(hKey);
1355 }
1356 }
1357
1358
1359 static VOID
1360 DisplayDeviceRelations(
1361 IN PDEVADVPROP_INFO dap,
1362 IN HWND hwndListView,
1363 IN ULONG ulFlags)
1364 {
1365 ULONG ulLength = 0;
1366 LPWSTR pszBuffer = NULL, pszStr;
1367 INT index = 0, len;
1368 CONFIGRET ret;
1369
1370 ret = CM_Get_Device_ID_List_Size_ExW(&ulLength,
1371 dap->szDeviceID,
1372 ulFlags,
1373 NULL);
1374 if (ret != CR_SUCCESS)
1375 return;
1376
1377 pszBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(),
1378 HEAP_ZERO_MEMORY,
1379 ulLength * sizeof(WCHAR));
1380 if (pszBuffer == NULL)
1381 return;
1382
1383 ret = CM_Get_Device_ID_List_ExW(dap->szDeviceID,
1384 pszBuffer,
1385 ulLength,
1386 ulFlags,
1387 NULL);
1388 if (ret != CR_SUCCESS)
1389 {
1390 HeapFree(GetProcessHeap(), 0, pszBuffer);
1391 return;
1392 }
1393
1394 pszStr = pszBuffer;
1395 index = 0;
1396 while (*pszStr != 0)
1397 {
1398 len = wcslen(pszStr) + 1;
1399
1400 SetListViewText(hwndListView, index, pszStr);
1401
1402 pszStr += len;
1403 index++;
1404 }
1405
1406 HeapFree(GetProcessHeap(), 0, pszBuffer);
1407 }
1408
1409
1410 static VOID
1411 DisplayCurrentPowerState(
1412 IN PDEVADVPROP_INFO dap,
1413 IN HWND hwndListView)
1414 {
1415 HDEVINFO DeviceInfoSet;
1416 PSP_DEVINFO_DATA DeviceInfoData;
1417 CM_POWER_DATA PowerData;
1418 DWORD dwSize, dwType;
1419 PCWSTR lpText = NULL;
1420
1421 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1422 {
1423 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1424 DeviceInfoData = &dap->CurrentDeviceInfoData;
1425 }
1426 else
1427 {
1428 DeviceInfoSet = dap->DeviceInfoSet;
1429 DeviceInfoData = &dap->DeviceInfoData;
1430 }
1431
1432 dwSize = sizeof(CM_POWER_DATA);
1433 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
1434 DeviceInfoData,
1435 SPDRP_DEVICE_POWER_DATA,
1436 &dwType,
1437 (LPBYTE)&PowerData,
1438 dwSize,
1439 &dwSize))
1440 return;
1441
1442 switch (PowerData.PD_MostRecentPowerState)
1443 {
1444 // case PowerDeviceUnspecified:
1445
1446 case PowerDeviceD0:
1447 lpText = L"D0";
1448 break;
1449
1450 case PowerDeviceD1:
1451 lpText = L"D1";
1452 break;
1453
1454 case PowerDeviceD2:
1455 lpText = L"D2";
1456 break;
1457
1458 case PowerDeviceD3:
1459 lpText = L"D3";
1460 break;
1461
1462 default:
1463 break;
1464 }
1465
1466 if (lpText != NULL)
1467 SetListViewText(hwndListView, 0, lpText);
1468 }
1469
1470
1471 static VOID
1472 DisplayPowerCapabilities(
1473 IN PDEVADVPROP_INFO dap,
1474 IN HWND hwndListView)
1475 {
1476 HDEVINFO DeviceInfoSet;
1477 PSP_DEVINFO_DATA DeviceInfoData;
1478 CM_POWER_DATA PowerData;
1479 DWORD dwSize, dwType;
1480 INT index = 0;
1481
1482 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1483 {
1484 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1485 DeviceInfoData = &dap->CurrentDeviceInfoData;
1486 }
1487 else
1488 {
1489 DeviceInfoSet = dap->DeviceInfoSet;
1490 DeviceInfoData = &dap->DeviceInfoData;
1491 }
1492
1493 dwSize = sizeof(CM_POWER_DATA);
1494 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
1495 DeviceInfoData,
1496 SPDRP_DEVICE_POWER_DATA,
1497 &dwType,
1498 (LPBYTE)&PowerData,
1499 dwSize,
1500 &dwSize))
1501 return;
1502
1503 if (PowerData.PD_Capabilities & PDCAP_D0_SUPPORTED)
1504 SetListViewText(hwndListView, index++, L"PDCAP_D0_SUPPORTED");
1505
1506 if (PowerData.PD_Capabilities & PDCAP_D1_SUPPORTED)
1507 SetListViewText(hwndListView, index++, L"PDCAP_D1_SUPPORTED");
1508
1509 if (PowerData.PD_Capabilities & PDCAP_D2_SUPPORTED)
1510 SetListViewText(hwndListView, index++, L"PDCAP_D2_SUPPORTED");
1511
1512 if (PowerData.PD_Capabilities & PDCAP_D3_SUPPORTED)
1513 SetListViewText(hwndListView, index++, L"PDCAP_D3_SUPPORTED");
1514
1515 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D0_SUPPORTED)
1516 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D0_SUPPORTED");
1517
1518 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D1_SUPPORTED)
1519 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D1_SUPPORTED");
1520
1521 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D2_SUPPORTED)
1522 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D2_SUPPORTED");
1523
1524 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D3_SUPPORTED)
1525 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D3_SUPPORTED");
1526
1527 if (PowerData.PD_Capabilities & PDCAP_WARM_EJECT_SUPPORTED)
1528 SetListViewText(hwndListView, index++, L"PDCAP_WARM_EJECT_SUPPORTED");
1529 }
1530
1531
1532 static VOID
1533 DisplayPowerStateMappings(
1534 IN PDEVADVPROP_INFO dap,
1535 IN HWND hwndListView)
1536 {
1537 HDEVINFO DeviceInfoSet;
1538 PSP_DEVINFO_DATA DeviceInfoData;
1539 CM_POWER_DATA PowerData;
1540 DWORD dwSize, dwType;
1541 INT i;
1542 DEVICE_POWER_STATE PowerState;
1543 WCHAR szSystemStateBuffer[40];
1544 WCHAR szDeviceStateBuffer[40];
1545 WCHAR szOutBuffer[100];
1546
1547 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
1548 {
1549 DeviceInfoSet = dap->CurrentDeviceInfoSet;
1550 DeviceInfoData = &dap->CurrentDeviceInfoData;
1551 }
1552 else
1553 {
1554 DeviceInfoSet = dap->DeviceInfoSet;
1555 DeviceInfoData = &dap->DeviceInfoData;
1556 }
1557
1558 dwSize = sizeof(CM_POWER_DATA);
1559 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
1560 DeviceInfoData,
1561 SPDRP_DEVICE_POWER_DATA,
1562 &dwType,
1563 (LPBYTE)&PowerData,
1564 dwSize,
1565 &dwSize))
1566 return;
1567
1568 for (i = PowerSystemWorking; i < PowerSystemMaximum; i++)
1569 {
1570 PowerState = PowerData.PD_PowerStateMapping[i];
1571 if ((PowerState >= PowerDeviceUnspecified) && (PowerState <= PowerDeviceD3))
1572 {
1573 swprintf(szSystemStateBuffer, L"S%u", i - 1);
1574
1575 switch (PowerState)
1576 {
1577 case PowerDeviceUnspecified:
1578 wcscpy(szDeviceStateBuffer, L"Not specified");
1579 break;
1580
1581 case PowerDeviceD0:
1582 wcscpy(szDeviceStateBuffer, L"D0");
1583 break;
1584
1585 case PowerDeviceD1:
1586 wcscpy(szDeviceStateBuffer, L"D1");
1587 break;
1588
1589 case PowerDeviceD2:
1590 wcscpy(szDeviceStateBuffer, L"D2");
1591 break;
1592
1593 case PowerDeviceD3:
1594 wcscpy(szDeviceStateBuffer, L"D3");
1595 break;
1596
1597 default:
1598 break;
1599 }
1600
1601 swprintf(szOutBuffer, L"%s -> %s", szSystemStateBuffer, szDeviceStateBuffer);
1602 SetListViewText(hwndListView, i, szOutBuffer);
1603 }
1604 }
1605 }
1606
1607
1608 static VOID
1609 DisplayDeviceProperties(IN PDEVADVPROP_INFO dap,
1610 IN HWND hwndComboBox,
1611 IN HWND hwndListView)
1612 {
1613 INT Index;
1614
1615 Index = (INT)SendMessage(hwndComboBox,
1616 CB_GETCURSEL,
1617 0,
1618 0);
1619 if (Index == CB_ERR)
1620 return;
1621
1622 (void)ListView_DeleteAllItems(hwndListView);
1623
1624 switch (Index)
1625 {
1626 case 0: /* Device ID */
1627 SetListViewText(hwndListView, 0, dap->szDeviceID);
1628 break;
1629
1630 case 1: /* Hardware ID */
1631 DisplayDevicePropertyText(dap,
1632 hwndListView,
1633 SPDRP_HARDWAREID);
1634 break;
1635
1636 case 2: /* Compatible IDs */
1637 DisplayDevicePropertyText(dap,
1638 hwndListView,
1639 SPDRP_COMPATIBLEIDS);
1640 break;
1641
1642 case 3: /* Matching ID */
1643 DisplayMatchingDeviceId(dap,
1644 hwndListView);
1645 break;
1646
1647 case 4: /* Service */
1648 DisplayDevicePropertyText(dap,
1649 hwndListView,
1650 SPDRP_SERVICE);
1651 break;
1652
1653 case 5: /* Enumerator */
1654 DisplayDevNodeEnumerator(dap,
1655 hwndListView);
1656 break;
1657
1658 case 6: /* Capabilities */
1659 DisplayDevicePropertyText(dap,
1660 hwndListView,
1661 SPDRP_CAPABILITIES);
1662 break;
1663
1664 case 7: /* Devnode Flags */
1665 DisplayDevNodeFlags(dap,
1666 hwndListView);
1667 break;
1668
1669 case 8: /* Config Flags */
1670 DisplayDevicePropertyText(dap,
1671 hwndListView,
1672 SPDRP_CONFIGFLAGS);
1673 break;
1674
1675 case 9: /* CSConfig Flags */
1676 DisplayCsFlags(dap,
1677 hwndListView);
1678 break;
1679
1680 case 10: /* Ejection relation */
1681 DisplayDeviceRelations(dap,
1682 hwndListView,
1683 CM_GETIDLIST_FILTER_EJECTRELATIONS);
1684 break;
1685
1686 case 11: /* Removal relations */
1687 DisplayDeviceRelations(dap,
1688 hwndListView,
1689 CM_GETIDLIST_FILTER_REMOVALRELATIONS);
1690 break;
1691
1692 case 12: /* Bus relation */
1693 DisplayDeviceRelations(dap,
1694 hwndListView,
1695 CM_GETIDLIST_FILTER_BUSRELATIONS);
1696 break;
1697
1698 case 13: /* Device Upper Filters */
1699 DisplayDevicePropertyText(dap,
1700 hwndListView,
1701 SPDRP_UPPERFILTERS);
1702 break;
1703
1704 case 14: /* Device Lower Filters */
1705 DisplayDevicePropertyText(dap,
1706 hwndListView,
1707 SPDRP_LOWERFILTERS);
1708 break;
1709
1710 case 15: /* Class Upper Filters */
1711 DisplayClassProperties(dap,
1712 hwndListView,
1713 L"UpperFilters");
1714 break;
1715
1716 case 16: /* Class Lower Filters */
1717 DisplayClassProperties(dap,
1718 hwndListView,
1719 L"LowerFilters");
1720 break;
1721
1722 case 17: /* Class Installer */
1723 DisplayClassProperties(dap,
1724 hwndListView,
1725 L"Installer32");
1726 break;
1727
1728 case 18: /* Class Coinstaller */
1729 DisplayClassCoinstallers(dap,
1730 hwndListView);
1731 break;
1732
1733 case 19: /* Device Coinstaller */
1734 DisplayDeviceCoinstallers(dap,
1735 hwndListView);
1736 break;
1737
1738 #if 0
1739 case 20: /* Firmware Revision */
1740 break;
1741 #endif
1742
1743 case 21: /* Current Power State */
1744 DisplayCurrentPowerState(dap,
1745 hwndListView);
1746 break;
1747
1748 case 22: /* Power Capabilities */
1749 DisplayPowerCapabilities(dap,
1750 hwndListView);
1751 break;
1752
1753 case 23: /* Power State Mappings */
1754 DisplayPowerStateMappings(dap,
1755 hwndListView);
1756 break;
1757
1758 default:
1759 SetListViewText(hwndListView, 0, L"<Not implemented yet>");
1760 break;
1761 }
1762 }
1763
1764
1765 static INT_PTR
1766 CALLBACK
1767 AdvProcDetailsDlgProc(IN HWND hwndDlg,
1768 IN UINT uMsg,
1769 IN WPARAM wParam,
1770 IN LPARAM lParam)
1771 {
1772 PDEVADVPROP_INFO dap;
1773 INT_PTR Ret = FALSE;
1774
1775 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER);
1776
1777 if (dap != NULL || uMsg == WM_INITDIALOG)
1778 {
1779 switch (uMsg)
1780 {
1781 case WM_COMMAND:
1782 {
1783 switch (LOWORD(wParam))
1784 {
1785 case IDC_DETAILSPROPNAME:
1786 if (HIWORD(wParam) == CBN_SELCHANGE)
1787 {
1788 DisplayDeviceProperties(dap,
1789 GetDlgItem(hwndDlg, IDC_DETAILSPROPNAME),
1790 GetDlgItem(hwndDlg, IDC_DETAILSPROPVALUE));
1791 }
1792 break;
1793 }
1794 break;
1795 }
1796
1797 case WM_NOTIFY:
1798 {
1799 NMHDR *hdr = (NMHDR*)lParam;
1800 switch (hdr->code)
1801 {
1802 case PSN_APPLY:
1803 break;
1804 }
1805 break;
1806 }
1807
1808 case WM_INITDIALOG:
1809 {
1810 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
1811 if (dap != NULL)
1812 {
1813 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap);
1814
1815 UpdateDetailsDlg(hwndDlg,
1816 dap);
1817 }
1818 Ret = TRUE;
1819 break;
1820 }
1821 }
1822 }
1823
1824 return Ret;
1825 }
1826
1827
1828 static VOID
1829 InitDevUsageActions(IN HWND hwndDlg,
1830 IN HWND hComboBox,
1831 IN PDEVADVPROP_INFO dap)
1832 {
1833 INT Index;
1834 UINT i;
1835 UINT Actions[] =
1836 {
1837 IDS_ENABLEDEVICE,
1838 IDS_DISABLEDEVICE,
1839 };
1840
1841 for (i = 0;
1842 i != sizeof(Actions) / sizeof(Actions[0]);
1843 i++)
1844 {
1845 /* fill in the device usage combo box */
1846 if (LoadString(hDllInstance,
1847 Actions[i],
1848 dap->szTemp,
1849 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
1850 {
1851 Index = (INT)SendMessage(hComboBox,
1852 CB_ADDSTRING,
1853 0,
1854 (LPARAM)dap->szTemp);
1855 if (Index != CB_ERR)
1856 {
1857 SendMessage(hComboBox,
1858 CB_SETITEMDATA,
1859 (WPARAM)Index,
1860 (LPARAM)Actions[i]);
1861
1862 switch (Actions[i])
1863 {
1864 case IDS_ENABLEDEVICE:
1865 if (dap->DeviceStarted)
1866 {
1867 SendMessage(hComboBox,
1868 CB_SETCURSEL,
1869 (WPARAM)Index,
1870 0);
1871 }
1872 break;
1873
1874 case IDS_DISABLEDEVICE:
1875 if (!dap->DeviceStarted)
1876 {
1877 SendMessage(hComboBox,
1878 CB_SETCURSEL,
1879 (WPARAM)Index,
1880 0);
1881 }
1882 break;
1883
1884 default:
1885 break;
1886 }
1887 }
1888 }
1889 }
1890 }
1891
1892
1893 static UINT
1894 GetSelectedUsageAction(IN HWND hComboBox)
1895 {
1896 INT Index;
1897 UINT Ret = 0;
1898
1899 Index = (INT)SendMessage(hComboBox,
1900 CB_GETCURSEL,
1901 0,
1902 0);
1903 if (Index != CB_ERR)
1904 {
1905 INT iRet = (INT) SendMessage(hComboBox,
1906 CB_GETITEMDATA,
1907 (WPARAM)Index,
1908 0);
1909 if (iRet != CB_ERR)
1910 {
1911 Ret = (UINT)iRet;
1912 }
1913 }
1914
1915 return Ret;
1916 }
1917
1918
1919 static BOOL
1920 ApplyGeneralSettings(IN HWND hwndDlg,
1921 IN PDEVADVPROP_INFO dap)
1922 {
1923 BOOL Ret = FALSE;
1924
1925 if (dap->DeviceUsageChanged && dap->IsAdmin && dap->CanDisable)
1926 {
1927 UINT SelectedUsageAction;
1928 BOOL NeedReboot = FALSE;
1929
1930 SelectedUsageAction = GetSelectedUsageAction(GetDlgItem(hwndDlg,
1931 IDC_DEVUSAGE));
1932 switch (SelectedUsageAction)
1933 {
1934 case IDS_ENABLEDEVICE:
1935 if (!dap->DeviceStarted)
1936 {
1937 Ret = EnableDevice(dap->DeviceInfoSet,
1938 &dap->DeviceInfoData,
1939 TRUE,
1940 0,
1941 &NeedReboot);
1942 }
1943 break;
1944
1945 case IDS_DISABLEDEVICE:
1946 if (dap->DeviceStarted)
1947 {
1948 Ret = EnableDevice(dap->DeviceInfoSet,
1949 &dap->DeviceInfoData,
1950 FALSE,
1951 0,
1952 &NeedReboot);
1953 }
1954 break;
1955
1956 default:
1957 break;
1958 }
1959
1960 if (Ret)
1961 {
1962 if (NeedReboot)
1963 {
1964 /* make PropertySheet() return PSM_REBOOTSYSTEM */
1965 PropSheet_RebootSystem(hwndDlg);
1966 }
1967 }
1968 else
1969 {
1970 /* FIXME - display an error message */
1971 FIXME("Failed to enable/disable device! LastError: %d\n",
1972 GetLastError());
1973 }
1974 }
1975 else
1976 Ret = !dap->DeviceUsageChanged;
1977
1978 /* disable the apply button */
1979 PropSheet_UnChanged(GetParent(hwndDlg),
1980 hwndDlg);
1981 dap->DeviceUsageChanged = FALSE;
1982 return Ret;
1983 }
1984
1985
1986 static VOID
1987 UpdateDevInfo(IN HWND hwndDlg,
1988 IN PDEVADVPROP_INFO dap,
1989 IN BOOL ReOpen)
1990 {
1991 HWND hDevUsage, hPropSheetDlg, hDevProbBtn;
1992 CONFIGRET cr;
1993 ULONG Status, ProblemNumber;
1994 SP_DEVINSTALL_PARAMS_W InstallParams;
1995 UINT TroubleShootStrId = IDS_TROUBLESHOOTDEV;
1996 BOOL bFlag, bDevActionAvailable = TRUE;
1997 BOOL bDrvInstalled = FALSE;
1998 DWORD iPage;
1999 HDEVINFO DeviceInfoSet = NULL;
2000 PSP_DEVINFO_DATA DeviceInfoData = NULL;
2001 PROPSHEETHEADER psh;
2002 DWORD nDriverPages = 0;
2003 BOOL RecalcPages = FALSE;
2004
2005 hPropSheetDlg = GetParent(hwndDlg);
2006
2007 if (dap->PageInitialized)
2008 {
2009 /* switch to the General page */
2010 PropSheet_SetCurSelByID(hPropSheetDlg,
2011 IDD_DEVICEGENERAL);
2012
2013 /* remove and destroy the existing device property sheet pages */
2014 if (dap->DevPropSheets != NULL)
2015 {
2016 for (iPage = 0;
2017 iPage != dap->nDevPropSheets;
2018 iPage++)
2019 {
2020 if (dap->DevPropSheets[iPage] != NULL)
2021 {
2022 PropSheet_RemovePage(hPropSheetDlg,
2023 (WPARAM) -1,
2024 dap->DevPropSheets[iPage]);
2025 RecalcPages = TRUE;
2026 }
2027 }
2028 }
2029 }
2030
2031 iPage = 0;
2032
2033 if (dap->FreeDevPropSheets)
2034 {
2035 /* don't free the array if it's the one allocated in
2036 DisplayDeviceAdvancedProperties */
2037 HeapFree(GetProcessHeap(),
2038 0,
2039 dap->DevPropSheets);
2040
2041 dap->FreeDevPropSheets = FALSE;
2042 }
2043
2044 dap->DevPropSheets = NULL;
2045 dap->nDevPropSheets = 0;
2046
2047 if (ReOpen)
2048 {
2049 /* create a new device info set and re-open the device */
2050 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
2051 {
2052 SetupDiDestroyDeviceInfoList(dap->CurrentDeviceInfoSet);
2053 }
2054
2055 dap->ParentDevInst = 0;
2056 dap->CurrentDeviceInfoSet = SetupDiCreateDeviceInfoListEx(NULL,
2057 hwndDlg,
2058 dap->lpMachineName,
2059 NULL);
2060 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
2061 {
2062 if (SetupDiOpenDeviceInfo(dap->CurrentDeviceInfoSet,
2063 dap->szDeviceID,
2064 hwndDlg,
2065 0,
2066 &dap->CurrentDeviceInfoData))
2067 {
2068 if (dap->CloseDevInst)
2069 {
2070 SetupDiDestroyDeviceInfoList(dap->DeviceInfoSet);
2071 }
2072
2073 dap->CloseDevInst = TRUE;
2074 dap->DeviceInfoSet = dap->CurrentDeviceInfoSet;
2075 dap->DeviceInfoData = dap->CurrentDeviceInfoData;
2076 dap->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE;
2077 }
2078 else
2079 goto GetParentNode;
2080 }
2081 else
2082 {
2083 GetParentNode:
2084 /* get the parent node from the initial devinst */
2085 CM_Get_Parent_Ex(&dap->ParentDevInst,
2086 dap->DeviceInfoData.DevInst,
2087 0,
2088 dap->hMachine);
2089 }
2090
2091 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
2092 {
2093 DeviceInfoSet = dap->CurrentDeviceInfoSet;
2094 DeviceInfoData = &dap->CurrentDeviceInfoData;
2095 }
2096 else
2097 {
2098 DeviceInfoSet = dap->DeviceInfoSet;
2099 DeviceInfoData = &dap->DeviceInfoData;
2100 }
2101 }
2102 else
2103 {
2104 DeviceInfoSet = dap->DeviceInfoSet;
2105 DeviceInfoData = &dap->DeviceInfoData;
2106 }
2107
2108 dap->HasDriverPage = FALSE;
2109 dap->HasResourcePage = FALSE;
2110 dap->HasPowerPage = FALSE;
2111 if (IsDriverInstalled(DeviceInfoData->DevInst,
2112 dap->hMachine,
2113 &bDrvInstalled) &&
2114 bDrvInstalled)
2115 {
2116 if (SetupDiCallClassInstaller((dap->ShowRemotePages ?
2117 DIF_ADDREMOTEPROPERTYPAGE_ADVANCED :
2118 DIF_ADDPROPERTYPAGE_ADVANCED),
2119 DeviceInfoSet,
2120 DeviceInfoData))
2121 {
2122 /* get install params */
2123 InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
2124 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet,
2125 DeviceInfoData,
2126 &InstallParams))
2127 {
2128 /* zero the flags */
2129 InstallParams.Flags = 0;
2130 }
2131
2132 dap->HasDriverPage = !(InstallParams.Flags & DI_DRIVERPAGE_ADDED);
2133 dap->HasResourcePage = !(InstallParams.Flags & DI_RESOURCEPAGE_ADDED);
2134 dap->HasPowerPage = !(InstallParams.Flags & DI_FLAGSEX_POWERPAGE_ADDED);
2135 }
2136 }
2137
2138 /* get the device icon */
2139 if (dap->hDevIcon != NULL)
2140 {
2141 DestroyIcon(dap->hDevIcon);
2142 dap->hDevIcon = NULL;
2143 }
2144 if (!SetupDiLoadClassIcon(&DeviceInfoData->ClassGuid,
2145 &dap->hDevIcon,
2146 NULL))
2147 {
2148 dap->hDevIcon = NULL;
2149 }
2150
2151 /* get the device name */
2152 if (GetDeviceDescriptionString(DeviceInfoSet,
2153 DeviceInfoData,
2154 dap->szDevName,
2155 sizeof(dap->szDevName) / sizeof(dap->szDevName[0])))
2156 {
2157 PropSheet_SetTitle(hPropSheetDlg,
2158 PSH_PROPTITLE,
2159 dap->szDevName);
2160 }
2161
2162 /* set the device image */
2163 SendDlgItemMessage(hwndDlg,
2164 IDC_DEVICON,
2165 STM_SETICON,
2166 (WPARAM)dap->hDevIcon,
2167 0);
2168
2169 /* set the device name edit control text */
2170 SetDlgItemText(hwndDlg,
2171 IDC_DEVNAME,
2172 dap->szDevName);
2173
2174 /* set the device type edit control text */
2175 if (GetDeviceTypeString(DeviceInfoData,
2176 dap->szTemp,
2177 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
2178 {
2179 SetDlgItemText(hwndDlg,
2180 IDC_DEVTYPE,
2181 dap->szTemp);
2182 }
2183
2184 /* set the device manufacturer edit control text */
2185 if (GetDeviceManufacturerString(DeviceInfoSet,
2186 DeviceInfoData,
2187 dap->szTemp,
2188 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
2189 {
2190 SetDlgItemText(hwndDlg,
2191 IDC_DEVMANUFACTURER,
2192 dap->szTemp);
2193 }
2194
2195 /* set the device location edit control text */
2196 if (GetDeviceLocationString(DeviceInfoSet,
2197 DeviceInfoData,
2198 dap->ParentDevInst,
2199 dap->szTemp,
2200 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
2201 {
2202 SetDlgItemText(hwndDlg,
2203 IDC_DEVLOCATION,
2204 dap->szTemp);
2205 }
2206
2207 /* set the device status edit control text */
2208 if (GetDeviceStatusString(DeviceInfoData->DevInst,
2209 dap->hMachine,
2210 dap->szTemp,
2211 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
2212 {
2213 SetDlgItemText(hwndDlg,
2214 IDC_DEVSTATUS,
2215 dap->szTemp);
2216 }
2217
2218 /* set the device troubleshoot button text and disable it if necessary */
2219 hDevProbBtn = GetDlgItem(hwndDlg,
2220 IDC_DEVPROBLEM);
2221 cr = CM_Get_DevNode_Status_Ex(&Status,
2222 &ProblemNumber,
2223 DeviceInfoData->DevInst,
2224 0,
2225 dap->hMachine);
2226 if (cr == CR_SUCCESS && (Status & DN_HAS_PROBLEM))
2227 {
2228 switch (ProblemNumber)
2229 {
2230 case CM_PROB_DEVLOADER_FAILED:
2231 {
2232 /* FIXME - only if it's not a root bus devloader,
2233 disable the button otherwise */
2234 TroubleShootStrId = IDS_UPDATEDRV;
2235 break;
2236 }
2237
2238 case CM_PROB_OUT_OF_MEMORY:
2239 case CM_PROB_ENTRY_IS_WRONG_TYPE:
2240 case CM_PROB_LACKED_ARBITRATOR:
2241 case CM_PROB_FAILED_START:
2242 case CM_PROB_LIAR:
2243 case CM_PROB_UNKNOWN_RESOURCE:
2244 {
2245 TroubleShootStrId = IDS_UPDATEDRV;
2246 break;
2247 }
2248
2249 case CM_PROB_BOOT_CONFIG_CONFLICT:
2250 case CM_PROB_NORMAL_CONFLICT:
2251 case CM_PROB_REENUMERATION:
2252 {
2253 /* FIXME - Troubleshoot conflict */
2254 break;
2255 }
2256
2257 case CM_PROB_FAILED_FILTER:
2258 case CM_PROB_REINSTALL:
2259 case CM_PROB_FAILED_INSTALL:
2260 {
2261 TroubleShootStrId = IDS_REINSTALLDRV;
2262 break;
2263 }
2264
2265 case CM_PROB_DEVLOADER_NOT_FOUND:
2266 {
2267 /* FIXME - 4 cases:
2268 1) if it's a missing system devloader:
2269 - disable the button (Reinstall Driver)
2270 2) if it's not a system devloader but still missing:
2271 - Reinstall Driver
2272 3) if it's not a system devloader but the file can be found:
2273 - Update Driver
2274 4) if it's a missing or empty software key
2275 - Update Driver
2276 */
2277 break;
2278 }
2279
2280 case CM_PROB_INVALID_DATA:
2281 case CM_PROB_PARTIAL_LOG_CONF:
2282 case CM_PROB_NO_VALID_LOG_CONF:
2283 case CM_PROB_HARDWARE_DISABLED:
2284 case CM_PROB_CANT_SHARE_IRQ:
2285 case CM_PROB_TRANSLATION_FAILED:
2286 case CM_PROB_SYSTEM_SHUTDOWN:
2287 case CM_PROB_PHANTOM:
2288 bDevActionAvailable = FALSE;
2289 break;
2290
2291 case CM_PROB_NOT_VERIFIED:
2292 case CM_PROB_DEVICE_NOT_THERE:
2293 /* FIXME - search hardware */
2294 break;
2295
2296 case CM_PROB_NEED_RESTART:
2297 case CM_PROB_WILL_BE_REMOVED:
2298 case CM_PROB_MOVED:
2299 case CM_PROB_TOO_EARLY:
2300 case CM_PROB_DISABLED_SERVICE:
2301 TroubleShootStrId = IDS_REBOOT;
2302 break;
2303
2304 case CM_PROB_REGISTRY:
2305 /* FIXME - check registry? */
2306 break;
2307
2308 case CM_PROB_DISABLED:
2309 /* if device was disabled by the user: */
2310 TroubleShootStrId = IDS_ENABLEDEV;
2311 /* FIXME - otherwise disable button because the device was
2312 disabled by the system*/
2313 break;
2314
2315 case CM_PROB_DEVLOADER_NOT_READY:
2316 /* FIXME - if it's a graphics adapter:
2317 - if it's a a secondary adapter and the main adapter
2318 couldn't be found
2319 - disable button
2320 - else
2321 - Properties
2322 - else
2323 - Update driver
2324 */
2325 break;
2326
2327 case CM_PROB_FAILED_ADD:
2328 TroubleShootStrId = IDS_PROPERTIES;
2329 break;
2330 }
2331 }
2332
2333 if (LoadString(hDllInstance,
2334 TroubleShootStrId,
2335 dap->szTemp,
2336 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])) != 0)
2337 {
2338 SetWindowText(hDevProbBtn,
2339 dap->szTemp);
2340 }
2341 EnableWindow(hDevProbBtn,
2342 dap->IsAdmin && bDevActionAvailable);
2343
2344 /* check if the device can be enabled/disabled */
2345 hDevUsage = GetDlgItem(hwndDlg,
2346 IDC_DEVUSAGE);
2347
2348 dap->CanDisable = FALSE;
2349 dap->DeviceStarted = FALSE;
2350
2351 if (CanDisableDevice(DeviceInfoData->DevInst,
2352 dap->hMachine,
2353 &bFlag))
2354 {
2355 dap->CanDisable = bFlag;
2356 }
2357
2358 if (IsDeviceStarted(DeviceInfoData->DevInst,
2359 dap->hMachine,
2360 &bFlag))
2361 {
2362 dap->DeviceStarted = bFlag;
2363 }
2364
2365 /* enable/disable the device usage controls */
2366 EnableWindow(GetDlgItem(hwndDlg,
2367 IDC_DEVUSAGELABEL),
2368 dap->CanDisable && dap->IsAdmin);
2369 EnableWindow(hDevUsage,
2370 dap->CanDisable && dap->IsAdmin);
2371
2372 /* clear the combobox */
2373 SendMessage(hDevUsage,
2374 CB_RESETCONTENT,
2375 0,
2376 0);
2377 if (dap->CanDisable)
2378 {
2379 InitDevUsageActions(hwndDlg,
2380 hDevUsage,
2381 dap);
2382 }
2383
2384 /* find out how many new device property sheets to add.
2385 fake a PROPSHEETHEADER structure, we don't plan to
2386 call PropertySheet again!*/
2387 psh.dwSize = sizeof(PROPSHEETHEADER);
2388 psh.dwFlags = 0;
2389 psh.nPages = 0;
2390
2391 /* get the number of device property sheets for the device */
2392 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet,
2393 DeviceInfoData,
2394 &psh,
2395 0,
2396 &nDriverPages,
2397 dap->PropertySheetType) &&
2398 nDriverPages != 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
2399 {
2400 dap->nDevPropSheets += nDriverPages;
2401 }
2402 else
2403 {
2404 nDriverPages = 0;
2405 }
2406
2407 /* include the driver page */
2408 if (dap->HasDriverPage)
2409 dap->nDevPropSheets++;
2410
2411 /* include the details page */
2412 if (dap->Extended)
2413 dap->nDevPropSheets++;
2414
2415 if (dap->HasResourcePage)
2416 dap->nDevPropSheets++;
2417
2418 /* add the device property sheets */
2419 if (dap->nDevPropSheets != 0)
2420 {
2421 dap->DevPropSheets = (HPROPSHEETPAGE *)HeapAlloc(GetProcessHeap(),
2422 HEAP_ZERO_MEMORY,
2423 dap->nDevPropSheets * sizeof(HPROPSHEETPAGE));
2424 if (dap->DevPropSheets != NULL)
2425 {
2426 if (nDriverPages != 0)
2427 {
2428 psh.phpage = dap->DevPropSheets;
2429
2430 /* query the device property sheet pages to add */
2431 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet,
2432 DeviceInfoData,
2433 &psh,
2434 dap->nDevPropSheets,
2435 NULL,
2436 dap->PropertySheetType))
2437 {
2438 /* add the property sheets */
2439 for (iPage = 0;
2440 iPage < nDriverPages;
2441 iPage++)
2442 {
2443 if (PropSheet_AddPage(hPropSheetDlg,
2444 dap->DevPropSheets[iPage]))
2445 {
2446 RecalcPages = TRUE;
2447 }
2448 }
2449
2450 dap->FreeDevPropSheets = TRUE;
2451 }
2452 else
2453 {
2454 /* cleanup, we were unable to get the device property sheets */
2455 iPage = nDriverPages;
2456 dap->nDevPropSheets -= nDriverPages;
2457 nDriverPages = 0;
2458 }
2459 }
2460 else
2461 iPage = 0;
2462
2463 /* add the driver page if necessary */
2464 if (dap->HasDriverPage)
2465 {
2466 PROPSHEETPAGE pspDriver = {0};
2467 pspDriver.dwSize = sizeof(PROPSHEETPAGE);
2468 pspDriver.dwFlags = PSP_DEFAULT;
2469 pspDriver.hInstance = hDllInstance;
2470 pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDRIVER);
2471 pspDriver.pfnDlgProc = AdvProcDriverDlgProc;
2472 pspDriver.lParam = (LPARAM)dap;
2473 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver);
2474 if (dap->DevPropSheets[iPage] != NULL)
2475 {
2476 if (PropSheet_AddPage(hPropSheetDlg,
2477 dap->DevPropSheets[iPage]))
2478 {
2479 iPage++;
2480 RecalcPages = TRUE;
2481 }
2482 else
2483 {
2484 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]);
2485 dap->DevPropSheets[iPage] = NULL;
2486 }
2487 }
2488 }
2489
2490 if (dap->Extended)
2491 {
2492 /* Add the details page */
2493 PROPSHEETPAGE pspDetails = {0};
2494 pspDetails.dwSize = sizeof(PROPSHEETPAGE);
2495 pspDetails.dwFlags = PSP_DEFAULT;
2496 pspDetails.hInstance = hDllInstance;
2497 pspDetails.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDETAILS);
2498 pspDetails.pfnDlgProc = AdvProcDetailsDlgProc;
2499 pspDetails.lParam = (LPARAM)dap;
2500 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDetails);
2501 if (dap->DevPropSheets[iPage] != NULL)
2502 {
2503 if (PropSheet_AddPage(hPropSheetDlg,
2504 dap->DevPropSheets[iPage]))
2505 {
2506 iPage++;
2507 RecalcPages = TRUE;
2508 }
2509 else
2510 {
2511 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]);
2512 dap->DevPropSheets[iPage] = NULL;
2513 }
2514 }
2515 }
2516
2517 if (dap->HasResourcePage)
2518 {
2519 PROPSHEETPAGE pspDriver = {0};
2520 pspDriver.dwSize = sizeof(PROPSHEETPAGE);
2521 pspDriver.dwFlags = PSP_DEFAULT;
2522 pspDriver.hInstance = hDllInstance;
2523 pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICERESOURCES);
2524 pspDriver.pfnDlgProc = ResourcesProcDriverDlgProc;
2525 pspDriver.lParam = (LPARAM)dap;
2526 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver);
2527 if (dap->DevPropSheets[iPage] != NULL)
2528 {
2529 if (PropSheet_AddPage(hPropSheetDlg,
2530 dap->DevPropSheets[iPage]))
2531 {
2532 iPage++;
2533 RecalcPages = TRUE;
2534 }
2535 else
2536 {
2537 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]);
2538 dap->DevPropSheets[iPage] = NULL;
2539 }
2540 }
2541 }
2542 /* FIXME: Add the power page */
2543 }
2544 else
2545 dap->nDevPropSheets = 0;
2546 }
2547
2548 if (RecalcPages)
2549 {
2550 PropSheet_RecalcPageSizes(hPropSheetDlg);
2551 }
2552
2553 /* finally, disable the apply button */
2554 PropSheet_UnChanged(hPropSheetDlg,
2555 hwndDlg);
2556 dap->DeviceUsageChanged = FALSE;
2557 }
2558
2559
2560 static LRESULT
2561 CALLBACK
2562 DlgParentSubWndProc(IN HWND hwnd,
2563 IN UINT uMsg,
2564 IN WPARAM wParam,
2565 IN LPARAM lParam)
2566 {
2567 PDEVADVPROP_INFO dap;
2568
2569 dap = (PDEVADVPROP_INFO)GetProp(hwnd,
2570 L"DevMgrDevChangeSub");
2571 if (dap != NULL)
2572 {
2573 if (uMsg == WM_DEVICECHANGE && !IsWindowVisible(dap->hWndGeneralPage))
2574 {
2575 SendMessage(dap->hWndGeneralPage,
2576 WM_DEVICECHANGE,
2577 wParam,
2578 lParam);
2579 }
2580
2581 /* pass the message the the old window proc */
2582 return CallWindowProc(dap->ParentOldWndProc,
2583 hwnd,
2584 uMsg,
2585 wParam,
2586 lParam);
2587 }
2588 else
2589 {
2590 /* this is not a good idea if the subclassed window was an ansi
2591 window, but we failed finding out the previous window proc
2592 so we can't use CallWindowProc. This should rarely - if ever -
2593 happen. */
2594
2595 return DefWindowProc(hwnd,
2596 uMsg,
2597 wParam,
2598 lParam);
2599 }
2600 }
2601
2602
2603 static INT_PTR
2604 CALLBACK
2605 AdvPropGeneralDlgProc(IN HWND hwndDlg,
2606 IN UINT uMsg,
2607 IN WPARAM wParam,
2608 IN LPARAM lParam)
2609 {
2610 PDEVADVPROP_INFO dap;
2611 INT_PTR Ret = FALSE;
2612
2613 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER);
2614
2615 if (dap != NULL || uMsg == WM_INITDIALOG)
2616 {
2617 switch (uMsg)
2618 {
2619 case WM_COMMAND:
2620 {
2621 switch (LOWORD(wParam))
2622 {
2623 case IDC_DEVUSAGE:
2624 {
2625 if (HIWORD(wParam) == CBN_SELCHANGE)
2626 {
2627 PropSheet_Changed(GetParent(hwndDlg),
2628 hwndDlg);
2629 dap->DeviceUsageChanged = TRUE;
2630 }
2631 break;
2632 }
2633
2634 case IDC_DEVPROBLEM:
2635 {
2636 if (dap->IsAdmin)
2637 {
2638 /* display the device problem wizard */
2639 ShowDeviceProblemWizard(hwndDlg,
2640 dap->DeviceInfoSet,
2641 &dap->DeviceInfoData,
2642 dap->hMachine);
2643 }
2644 break;
2645 }
2646 }
2647 break;
2648 }
2649
2650 case WM_NOTIFY:
2651 {
2652 NMHDR *hdr = (NMHDR*)lParam;
2653 switch (hdr->code)
2654 {
2655 case PSN_APPLY:
2656 ApplyGeneralSettings(hwndDlg,
2657 dap);
2658 break;
2659 }
2660 break;
2661 }
2662
2663 case WM_INITDIALOG:
2664 {
2665 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
2666 if (dap != NULL)
2667 {
2668 HWND hWndParent;
2669
2670 dap->hWndGeneralPage = hwndDlg;
2671
2672 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap);
2673
2674 /* subclass the parent window to always receive
2675 WM_DEVICECHANGE messages */
2676 hWndParent = GetParent(hwndDlg);
2677 if (hWndParent != NULL)
2678 {
2679 /* subclass the parent window. This is not safe
2680 if the parent window belongs to another thread! */
2681 dap->ParentOldWndProc = (WNDPROC)SetWindowLongPtr(hWndParent,
2682 GWLP_WNDPROC,
2683 (LONG_PTR)DlgParentSubWndProc);
2684
2685 if (dap->ParentOldWndProc != NULL &&
2686 SetProp(hWndParent,
2687 L"DevMgrDevChangeSub",
2688 (HANDLE)dap))
2689 {
2690 dap->hWndParent = hWndParent;
2691 }
2692 }
2693
2694 /* do not call UpdateDevInfo directly in here because it modifies
2695 the pages of the property sheet! */
2696 PostMessage(hwndDlg,
2697 PM_INITIALIZE,
2698 0,
2699 0);
2700 }
2701 Ret = TRUE;
2702 break;
2703 }
2704
2705 case WM_DEVICECHANGE:
2706 {
2707 /* FIXME - don't call UpdateDevInfo for all events */
2708 UpdateDevInfo(hwndDlg,
2709 dap,
2710 TRUE);
2711 Ret = TRUE;
2712 break;
2713 }
2714
2715 case PM_INITIALIZE:
2716 {
2717 UpdateDevInfo(hwndDlg,
2718 dap,
2719 FALSE);
2720 dap->PageInitialized = TRUE;
2721 break;
2722 }
2723
2724 case WM_DESTROY:
2725 {
2726 /* restore the old window proc of the subclassed parent window */
2727 if (dap->hWndParent != NULL && dap->ParentOldWndProc != NULL)
2728 {
2729 if (SetWindowLongPtr(dap->hWndParent,
2730 GWLP_WNDPROC,
2731 (LONG_PTR)dap->ParentOldWndProc) == (LONG_PTR)DlgParentSubWndProc)
2732 {
2733 RemoveProp(dap->hWndParent,
2734 L"DevMgrDevChangeSub");
2735 }
2736 }
2737 break;
2738 }
2739 }
2740 }
2741
2742 return Ret;
2743 }
2744
2745
2746 INT_PTR
2747 DisplayDeviceAdvancedProperties(IN HWND hWndParent,
2748 IN LPCWSTR lpDeviceID OPTIONAL,
2749 IN HDEVINFO DeviceInfoSet,
2750 IN PSP_DEVINFO_DATA DeviceInfoData,
2751 IN HINSTANCE hComCtl32,
2752 IN LPCWSTR lpMachineName,
2753 IN DWORD dwFlags)
2754 {
2755 PROPSHEETHEADER psh = {0};
2756 PROPSHEETPAGE pspGeneral = {0};
2757 PPROPERTYSHEETW pPropertySheetW;
2758 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW;
2759 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage;
2760 PDEVADVPROP_INFO DevAdvPropInfo;
2761 HMACHINE hMachine = NULL;
2762 DWORD DevIdSize = 0;
2763 INT_PTR Ret = -1;
2764
2765 /* we don't want to statically link against comctl32, so find the
2766 functions we need dynamically */
2767 pPropertySheetW =
2768 (PPROPERTYSHEETW)GetProcAddress(hComCtl32,
2769 "PropertySheetW");
2770 pCreatePropertySheetPageW =
2771 (PCREATEPROPERTYSHEETPAGEW)GetProcAddress(hComCtl32,
2772 "CreatePropertySheetPageW");
2773 pDestroyPropertySheetPage =
2774 (PDESTROYPROPERTYSHEETPAGE)GetProcAddress(hComCtl32,
2775 "DestroyPropertySheetPage");
2776 if (pPropertySheetW == NULL ||
2777 pCreatePropertySheetPageW == NULL ||
2778 pDestroyPropertySheetPage == NULL)
2779 {
2780 return -1;
2781 }
2782
2783 if (lpDeviceID == NULL)
2784 {
2785 /* find out how much size is needed for the device id */
2786 if (SetupDiGetDeviceInstanceId(DeviceInfoSet,
2787 DeviceInfoData,
2788 NULL,
2789 0,
2790 &DevIdSize))
2791 {
2792 ERR("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
2793 return -1;
2794 }
2795
2796 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
2797 {
2798 return -1;
2799 }
2800 }
2801 else
2802 {
2803 DevIdSize = (DWORD)wcslen(lpDeviceID) + 1;
2804 }
2805
2806 if (lpMachineName != NULL && lpMachineName[0] != L'\0')
2807 {
2808 CONFIGRET cr = CM_Connect_Machine(lpMachineName,
2809 &hMachine);
2810 if (cr != CR_SUCCESS)
2811 {
2812 return -1;
2813 }
2814 }
2815
2816 /* create the internal structure associated with the "General",
2817 "Driver", ... pages */
2818 DevAdvPropInfo = (PDEVADVPROP_INFO)HeapAlloc(GetProcessHeap(),
2819 HEAP_ZERO_MEMORY,
2820 FIELD_OFFSET(DEVADVPROP_INFO,
2821 szDeviceID) +
2822 (DevIdSize * sizeof(WCHAR)));
2823 if (DevAdvPropInfo == NULL)
2824 {
2825 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2826 goto Cleanup;
2827 }
2828
2829 if (lpDeviceID == NULL)
2830 {
2831 /* read the device instance id */
2832 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet,
2833 DeviceInfoData,
2834 DevAdvPropInfo->szDeviceID,
2835 DevIdSize,
2836 NULL))
2837 {
2838 goto Cleanup;
2839 }
2840 }
2841 else
2842 {
2843 /* copy the device instance id supplied by the caller */
2844 wcscpy(DevAdvPropInfo->szDeviceID,
2845 lpDeviceID);
2846 }
2847
2848 DevAdvPropInfo->DeviceInfoSet = DeviceInfoSet;
2849 DevAdvPropInfo->DeviceInfoData = *DeviceInfoData;
2850 DevAdvPropInfo->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE;
2851 DevAdvPropInfo->CurrentDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
2852
2853 DevAdvPropInfo->ShowRemotePages = (lpMachineName != NULL && lpMachineName[0] != L'\0');
2854 DevAdvPropInfo->hMachine = hMachine;
2855 DevAdvPropInfo->lpMachineName = lpMachineName;
2856 DevAdvPropInfo->szDevName[0] = L'\0';
2857 DevAdvPropInfo->hComCtl32 = hComCtl32;
2858 DevAdvPropInfo->pCreatePropertySheetPageW = pCreatePropertySheetPageW;
2859 DevAdvPropInfo->pDestroyPropertySheetPage = pDestroyPropertySheetPage;
2860
2861 DevAdvPropInfo->IsAdmin = TRUE;// IsUserAdmin();
2862 DevAdvPropInfo->DoDefaultDevAction = ((dwFlags & DPF_DEVICE_STATUS_ACTION) != 0);
2863 DevAdvPropInfo->Extended = ((dwFlags & DPF_EXTENDED) != 0);
2864
2865 psh.dwSize = sizeof(PROPSHEETHEADER);
2866 psh.dwFlags = PSH_PROPTITLE | PSH_NOAPPLYNOW;
2867 psh.hwndParent = hWndParent;
2868 psh.pszCaption = DevAdvPropInfo->szDevName;
2869
2870 DevAdvPropInfo->PropertySheetType = DevAdvPropInfo->ShowRemotePages ?
2871 DIGCDP_FLAG_REMOTE_ADVANCED :
2872 DIGCDP_FLAG_ADVANCED;
2873
2874 psh.phpage = (HPROPSHEETPAGE *)HeapAlloc(GetProcessHeap(),
2875 HEAP_ZERO_MEMORY,
2876 1 * sizeof(HPROPSHEETPAGE));
2877 if (psh.phpage == NULL)
2878 {
2879 goto Cleanup;
2880 }
2881
2882 /* add the "General" property sheet */
2883 pspGeneral.dwSize = sizeof(PROPSHEETPAGE);
2884 pspGeneral.dwFlags = PSP_DEFAULT;
2885 pspGeneral.hInstance = hDllInstance;
2886 pspGeneral.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEGENERAL);
2887 pspGeneral.pfnDlgProc = AdvPropGeneralDlgProc;
2888 pspGeneral.lParam = (LPARAM)DevAdvPropInfo;
2889 psh.phpage[psh.nPages] = pCreatePropertySheetPageW(&pspGeneral);
2890 if (psh.phpage[psh.nPages] != NULL)
2891 {
2892 psh.nPages++;
2893 }
2894
2895 DevAdvPropInfo->nDevPropSheets = psh.nPages;
2896
2897 if (psh.nPages != 0)
2898 {
2899 Ret = pPropertySheetW(&psh);
2900
2901 /* NOTE: no need to destroy the property sheets anymore! */
2902 }
2903 else
2904 {
2905 UINT i;
2906
2907 Cleanup:
2908 /* in case of failure the property sheets must be destroyed */
2909 if (psh.phpage != NULL)
2910 {
2911 for (i = 0;
2912 i < psh.nPages;
2913 i++)
2914 {
2915 if (psh.phpage[i] != NULL)
2916 {
2917 pDestroyPropertySheetPage(psh.phpage[i]);
2918 }
2919 }
2920 }
2921 }
2922
2923 if (DevAdvPropInfo != NULL)
2924 {
2925 if (DevAdvPropInfo->FreeDevPropSheets)
2926 {
2927 /* don't free the array if it's the one allocated in
2928 DisplayDeviceAdvancedProperties */
2929 HeapFree(GetProcessHeap(),
2930 0,
2931 DevAdvPropInfo->DevPropSheets);
2932 }
2933
2934 if (DevAdvPropInfo->CloseDevInst)
2935 {
2936 /* close the device info set in case a new one was created */
2937 SetupDiDestroyDeviceInfoList(DevAdvPropInfo->DeviceInfoSet);
2938 }
2939
2940 if (DevAdvPropInfo->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
2941 {
2942 SetupDiDestroyDeviceInfoList(DevAdvPropInfo->CurrentDeviceInfoSet);
2943 }
2944
2945 if (DevAdvPropInfo->hDevIcon != NULL)
2946 {
2947 DestroyIcon(DevAdvPropInfo->hDevIcon);
2948 }
2949
2950 HeapFree(GetProcessHeap(),
2951 0,
2952 DevAdvPropInfo);
2953 }
2954
2955 if (psh.phpage != NULL)
2956 {
2957 HeapFree(GetProcessHeap(),
2958 0,
2959 psh.phpage);
2960 }
2961
2962 if (hMachine != NULL)
2963 {
2964 CM_Disconnect_Machine(hMachine);
2965 }
2966
2967 return Ret;
2968 }