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