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