10c5dfd7e315e9606acef0387222d84235617e2e
[reactos.git] / dll / cpl / hdwwiz / hdwwiz.c
1 /*
2 * ReactOS New devices installation
3 * Copyright (C) 2005, 2008 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 * PROJECT: ReactOS Add hardware control panel
21 * FILE: dll/cpl/hdwwiz/hdwwiz.c
22 * PURPOSE: ReactOS Add hardware control panel
23 * PROGRAMMER: Hervé Poussineau (hpoussin@reactos.org)
24 * Dmitry Chapyshev (dmitry@reactos.org)
25 */
26
27 #include "resource.h"
28 #include "hdwwiz.h"
29
30 /* GLOBALS ******************************************************************/
31
32 HINSTANCE hApplet = NULL;
33 HFONT hTitleFont;
34 SP_CLASSIMAGELIST_DATA ImageListData;
35 PWSTR pDeviceStatusText;
36 HANDLE hProcessHeap;
37 HDEVINFO hDevInfoTypes;
38
39 typedef BOOL (WINAPI *PINSTALL_NEW_DEVICE)(HWND, LPGUID, PDWORD);
40
41
42 /* STATIC FUNCTIONS *********************************************************/
43
44 static HFONT
45 CreateTitleFont(VOID)
46 {
47 NONCLIENTMETRICS ncm;
48 LOGFONT LogFont;
49 HDC hdc;
50 INT FontSize;
51 HFONT hFont;
52
53 ncm.cbSize = sizeof(NONCLIENTMETRICS);
54 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
55
56 LogFont = ncm.lfMessageFont;
57 LogFont.lfWeight = FW_BOLD;
58 wcscpy(LogFont.lfFaceName, L"MS Shell Dlg");
59
60 hdc = GetDC(NULL);
61 FontSize = 12;
62 LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72;
63 hFont = CreateFontIndirect(&LogFont);
64 ReleaseDC(NULL, hdc);
65
66 return hFont;
67 }
68
69 static INT_PTR CALLBACK
70 StartPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
71 {
72 switch (uMsg)
73 {
74 case WM_INITDIALOG:
75 {
76 /* Set title font */
77 SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE);
78 }
79 break;
80
81 case WM_NOTIFY:
82 {
83 LPNMHDR lpnm = (LPNMHDR)lParam;
84
85 switch (lpnm->code)
86 {
87 case PSN_SETACTIVE:
88 {
89 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
90 }
91 break;
92 }
93 }
94 break;
95 }
96
97 return FALSE;
98 }
99
100 static INT_PTR CALLBACK
101 SearchPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
102 {
103 switch (uMsg)
104 {
105 case WM_INITDIALOG:
106 {
107 /* TODO: PnP devices search */
108 }
109 break;
110
111 case WM_NOTIFY:
112 {
113 LPNMHDR lpnm = (LPNMHDR)lParam;
114
115 switch (lpnm->code)
116 {
117 case PSN_SETACTIVE:
118 {
119 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
120 }
121 break;
122 }
123 }
124 break;
125 }
126
127 return FALSE;
128 }
129
130 static INT_PTR CALLBACK
131 IsConnectedPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
132 {
133 switch (uMsg)
134 {
135 case WM_COMMAND:
136 {
137 if(HIWORD(wParam) == BN_CLICKED)
138 {
139 if ((SendDlgItemMessage(hwndDlg, IDC_CONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED) ||
140 (SendDlgItemMessage(hwndDlg, IDC_NOTCONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED))
141 {
142 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
143 }
144 else
145 {
146 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
147 }
148 }
149 }
150 break;
151
152 case WM_NOTIFY:
153 {
154 LPNMHDR lpnm = (LPNMHDR)lParam;
155
156 switch (lpnm->code)
157 {
158 case PSN_SETACTIVE:
159 {
160 if ((SendDlgItemMessage(hwndDlg, IDC_CONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED) ||
161 (SendDlgItemMessage(hwndDlg, IDC_NOTCONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED))
162 {
163 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
164 }
165 else
166 {
167 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
168 }
169 }
170 break;
171
172 case PSN_WIZNEXT:
173 {
174 if (SendDlgItemMessage(hwndDlg, IDC_NOTCONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED)
175 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NOTCONNECTEDPAGE);
176 else
177 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PROBELISTPAGE);
178
179 return TRUE;
180 }
181 }
182 }
183 break;
184 }
185
186 return FALSE;
187 }
188
189 static INT_PTR CALLBACK
190 FinishPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
191 {
192 switch (uMsg)
193 {
194 case WM_INITDIALOG:
195 {
196 /* Set title font */
197 SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE);
198 }
199 break;
200
201 case WM_NOTIFY:
202 {
203 LPNMHDR lpnm = (LPNMHDR)lParam;
204
205 switch (lpnm->code)
206 {
207 case PSN_SETACTIVE:
208 {
209 /* Only "Finish" button */
210 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
211 }
212 break;
213 }
214 }
215 break;
216 }
217
218 return FALSE;
219 }
220
221 static INT_PTR CALLBACK
222 NotConnectedPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
223 {
224 switch (uMsg)
225 {
226 case WM_INITDIALOG:
227 {
228 /* Set title font */
229 SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE);
230 }
231 break;
232
233 case WM_NOTIFY:
234 {
235 LPNMHDR lpnm = (LPNMHDR)lParam;
236
237 switch (lpnm->code)
238 {
239 case PSN_SETACTIVE:
240 {
241 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH | PSWIZB_BACK);
242 }
243 break;
244
245 case PSN_WIZBACK:
246 {
247 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_ISCONNECTEDPAGE);
248 return TRUE;
249 }
250 }
251 }
252 break;
253 }
254
255 return FALSE;
256 }
257
258 static VOID
259 TrimGuidString(LPWSTR szString, LPWSTR szNewString)
260 {
261 WCHAR szBuffer[39];
262 INT Index;
263
264 if (wcslen(szString) == 38)
265 {
266 if ((szString[0] == L'{') && (szString[37] == L'}'))
267 {
268 for (Index = 0; Index < wcslen(szString); Index++)
269 szBuffer[Index] = szString[Index + 1];
270
271 szBuffer[36] = L'\0';
272 wcscpy(szNewString, szBuffer);
273 return;
274 }
275 }
276 wcscpy(szNewString, L"\0");
277 }
278
279 static VOID
280 InitProbeListPage(HWND hwndDlg)
281 {
282 LV_COLUMN Column;
283 LV_ITEM Item;
284 WCHAR szBuffer[MAX_STR_SIZE], szGuid[MAX_STR_SIZE],
285 szTrimGuid[MAX_STR_SIZE], szStatusText[MAX_STR_SIZE];
286 HWND hList = GetDlgItem(hwndDlg, IDC_PROBELIST);
287 PWSTR pstrStatusText;
288 HDEVINFO hDevInfo;
289 SP_DEVINFO_DATA DevInfoData;
290 ULONG ulStatus, ulProblemNumber;
291 GUID ClassGuid;
292 RECT Rect;
293 DWORD Index;
294
295 if (!hList) return;
296
297 ZeroMemory(&Column, sizeof(LV_COLUMN));
298
299 GetClientRect(hList, &Rect);
300
301 Column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
302 Column.fmt = LVCFMT_LEFT;
303 Column.iSubItem = 0;
304 Column.pszText = NULL;
305 Column.cx = Rect.right - GetSystemMetrics(SM_CXVSCROLL);
306 (VOID) ListView_InsertColumn(hList, 0, &Column);
307
308 ZeroMemory(&Item, sizeof(LV_ITEM));
309
310 LoadString(hApplet, IDS_ADDNEWDEVICE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR));
311
312 Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
313 Item.pszText = (LPWSTR) szBuffer;
314 Item.iItem = (INT) ListView_GetItemCount(hList);
315 Item.iImage = -1;
316 (VOID) ListView_InsertItem(hList, &Item);
317
318 hDevInfo = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, 0);
319
320 if (hDevInfo == INVALID_HANDLE_VALUE) return;
321
322 /* Get the device image List */
323 ImageListData.cbSize = sizeof(ImageListData);
324 SetupDiGetClassImageList(&ImageListData);
325
326 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
327 for (Index = 0; TRUE; Index++)
328 {
329 szBuffer[0] = L'\0';
330
331 if (!SetupDiEnumDeviceInfo(hDevInfo, Index, &DevInfoData)) break;
332
333 if (CM_Get_DevNode_Status_Ex(&ulStatus, &ulProblemNumber, DevInfoData.DevInst, 0, NULL) == CR_SUCCESS)
334 {
335 if (ulStatus & DN_NO_SHOW_IN_DM) continue;
336 }
337
338 /* Get the device's friendly name */
339 if (!SetupDiGetDeviceRegistryProperty(hDevInfo,
340 &DevInfoData,
341 SPDRP_FRIENDLYNAME,
342 0,
343 (BYTE*)szBuffer,
344 MAX_STR_SIZE,
345 NULL))
346 {
347 /* If the friendly name fails, try the description instead */
348 SetupDiGetDeviceRegistryProperty(hDevInfo,
349 &DevInfoData,
350 SPDRP_DEVICEDESC,
351 0,
352 (BYTE*)szBuffer,
353 MAX_STR_SIZE,
354 NULL);
355 }
356
357 SetupDiGetDeviceRegistryProperty(hDevInfo,
358 &DevInfoData,
359 SPDRP_CLASSGUID,
360 0,
361 (BYTE*)szGuid,
362 MAX_STR_SIZE,
363 NULL);
364
365 TrimGuidString(szGuid, szTrimGuid);
366 UuidFromStringW(szTrimGuid, &ClassGuid);
367
368 SetupDiGetClassImageIndex(&ImageListData,
369 &ClassGuid,
370 &Item.iImage);
371
372 DeviceProblemTextW(NULL,
373 DevInfoData.DevInst,
374 ulProblemNumber,
375 szStatusText,
376 sizeof(szStatusText) / sizeof(WCHAR));
377
378 pstrStatusText = (PWSTR)HeapAlloc(hProcessHeap, 0, sizeof(szStatusText));
379 lstrcpy(pstrStatusText, szStatusText);
380
381 if (szBuffer[0] != L'\0')
382 {
383 /* Set device name */
384 Item.pszText = (LPWSTR) szBuffer;
385 Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
386 Item.lParam = (LPARAM) pstrStatusText;
387 Item.iItem = (INT) ListView_GetItemCount(hList);
388 (VOID) ListView_InsertItem(hList, &Item);
389 }
390
391 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
392 }
393
394 (VOID) ListView_SetImageList(hList, ImageListData.ImageList, LVSIL_SMALL);
395 (VOID) ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT);
396 SetupDiDestroyDeviceInfoList(hDevInfo);
397 }
398
399 static INT_PTR CALLBACK
400 ProbeListPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
401 {
402 INT Index;
403 LVITEM Item;
404
405 switch (uMsg)
406 {
407 case WM_INITDIALOG:
408 {
409 pDeviceStatusText = (PWSTR)HeapAlloc(hProcessHeap, 0, MAX_STR_SIZE);
410 InitProbeListPage(hwndDlg);
411 }
412 break;
413
414 case WM_NOTIFY:
415 {
416 LPNMHDR lpnm = (LPNMHDR)lParam;
417
418 switch (lpnm->code)
419 {
420 case PSN_SETACTIVE:
421 {
422 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
423 }
424 break;
425
426 case PSN_WIZNEXT:
427 {
428 Index = (INT) SendMessage(GetDlgItem(hwndDlg, IDC_PROBELIST), LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
429 if (Index == -1) Index = 0;
430
431 if (Index == 0)
432 {
433 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SELECTWAYPAGE);
434 }
435 else
436 {
437 LVITEM Item;
438 PWSTR pts;
439
440 ZeroMemory(&Item, sizeof(LV_ITEM));
441 Item.mask = LVIF_PARAM;
442 Item.iItem = Index;
443 (VOID) ListView_GetItem(GetDlgItem(hwndDlg, IDC_PROBELIST), &Item);
444 pts = (PWSTR) Item.lParam;
445 wcscpy(pDeviceStatusText, pts);
446
447 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_HWSTATUSPAGE);
448 }
449 return TRUE;
450 }
451 }
452 }
453 break;
454
455 case WM_DESTROY:
456 {
457 for (Index = ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_PROBELIST)); --Index > 0;)
458 {
459 ZeroMemory(&Item, sizeof(LV_ITEM));
460 Item.mask = LVIF_PARAM;
461 Item.iItem = Index;
462 (VOID) ListView_GetItem(GetDlgItem(hwndDlg, IDC_PROBELIST), &Item);
463 HeapFree(hProcessHeap, 0, (LPVOID) Item.lParam);
464 }
465 HeapFree(hProcessHeap, 0, (LPVOID) pDeviceStatusText);
466 }
467 break;
468 }
469
470 return FALSE;
471 }
472
473 static INT_PTR CALLBACK
474 SelectWayPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
475 {
476 switch (uMsg)
477 {
478 case WM_NOTIFY:
479 {
480 LPNMHDR lpnm = (LPNMHDR)lParam;
481
482 switch (lpnm->code)
483 {
484 case PSN_SETACTIVE:
485 {
486 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
487 if (SendDlgItemMessage(hwndDlg, IDC_AUTOINSTALL, BM_GETCHECK, 0, 0) == BST_CHECKED)
488 SendDlgItemMessage(hwndDlg, IDC_MANUALLYINST, BM_SETCHECK, 0, 0);
489 else
490 {
491 SendDlgItemMessage(hwndDlg, IDC_AUTOINSTALL, BM_SETCHECK, 1, 1);
492 SendDlgItemMessage(hwndDlg, IDC_MANUALLYINST, BM_SETCHECK, 0, 0);
493 }
494 }
495 break;
496
497 case PSN_WIZNEXT:
498 {
499 if (SendDlgItemMessage(hwndDlg, IDC_AUTOINSTALL, BM_GETCHECK, 0, 0) == BST_CHECKED)
500 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PROGRESSPAGE);
501 else
502 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_HWTYPESPAGE);
503
504 return TRUE;
505 }
506 }
507 }
508 break;
509 }
510
511 return FALSE;
512 }
513
514 static INT_PTR CALLBACK
515 DevStatusPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
516 {
517 switch (uMsg)
518 {
519 case WM_INITDIALOG:
520 {
521 /* Set title font */
522 SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE);
523 }
524 break;
525
526 case WM_NOTIFY:
527 {
528 LPNMHDR lpnm = (LPNMHDR)lParam;
529
530 switch (lpnm->code)
531 {
532 case PSN_SETACTIVE:
533 {
534 /* Set status text */
535 SetWindowText(GetDlgItem(hwndDlg, IDC_HWSTATUSEDIT), pDeviceStatusText);
536
537 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH | PSWIZB_BACK);
538 }
539 break;
540
541 case PSN_WIZBACK:
542 {
543 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PROBELISTPAGE);
544 return TRUE;
545 }
546 }
547 }
548 break;
549 }
550
551 return FALSE;
552 }
553
554 static INT
555 EnumDeviceClasses(INT ClassIndex,
556 LPWSTR DevClassName,
557 LPWSTR DevClassDesc,
558 BOOL *DevPresent,
559 INT *ClassImage)
560 {
561 GUID ClassGuid;
562 HKEY KeyClass;
563 WCHAR ClassName[MAX_STR_SIZE];
564 DWORD RequiredSize = MAX_STR_SIZE;
565 UINT Ret;
566
567 *DevPresent = FALSE;
568 *DevClassName = L'\0';
569
570 Ret = CM_Enumerate_Classes(ClassIndex,
571 &ClassGuid,
572 0);
573 if (Ret != CR_SUCCESS)
574 {
575 /* All classes enumerated */
576 if(Ret == CR_NO_SUCH_VALUE)
577 {
578 hDevInfoTypes = NULL;
579 return -1;
580 }
581
582 if (Ret == CR_INVALID_DATA)
583 {
584 ; /* FIXME: What should we do here? */
585 }
586
587 /* Handle other errors... */
588 }
589
590 if (SetupDiClassNameFromGuid(&ClassGuid,
591 ClassName,
592 RequiredSize,
593 &RequiredSize))
594 {
595 lstrcpy(DevClassName, ClassName);
596 }
597
598 if (!SetupDiGetClassImageIndex(&ImageListData,
599 &ClassGuid,
600 ClassImage))
601 {
602 /* FIXME: Can we do this?
603 * Set the blank icon: IDI_SETUPAPI_BLANK = 41
604 * It'll be image 24 in the imagelist */
605 *ClassImage = 24;
606 }
607
608 /* Get device info for all devices of a particular class */
609 hDevInfoTypes = SetupDiGetClassDevs(&ClassGuid,
610 NULL,
611 NULL,
612 DIGCF_PRESENT);
613 if (hDevInfoTypes == INVALID_HANDLE_VALUE)
614 {
615 hDevInfoTypes = NULL;
616 return 0;
617 }
618
619 KeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid,
620 MAXIMUM_ALLOWED,
621 DIOCR_INSTALLER,
622 NULL,
623 0);
624 if (KeyClass != INVALID_HANDLE_VALUE)
625 {
626
627 LONG dwSize = MAX_STR_SIZE;
628
629 if (RegQueryValue(KeyClass,
630 NULL,
631 DevClassDesc,
632 &dwSize) != ERROR_SUCCESS)
633 {
634 *DevClassDesc = L'\0';
635 }
636 }
637 else
638 {
639 return -3;
640 }
641
642 *DevPresent = TRUE;
643
644 RegCloseKey(KeyClass);
645
646 return 0;
647 }
648
649 static VOID
650 InitHardWareTypesPage(HWND hwndDlg)
651 {
652 HWND hList = GetDlgItem(hwndDlg, IDC_HWTYPESLIST);
653 WCHAR DevName[MAX_STR_SIZE];
654 WCHAR DevDesc[MAX_STR_SIZE];
655 BOOL DevExist = FALSE;
656 INT ClassRet, DevImage, Index = 0;
657 LV_COLUMN Column;
658 LV_ITEM Item;
659 RECT Rect;
660
661 if (!hList) return;
662
663 ZeroMemory(&Column, sizeof(LV_COLUMN));
664
665 GetClientRect(hList, &Rect);
666
667 Column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
668 Column.fmt = LVCFMT_LEFT;
669 Column.iSubItem = 0;
670 Column.pszText = NULL;
671 Column.cx = Rect.right - GetSystemMetrics(SM_CXVSCROLL);
672 (VOID) ListView_InsertColumn(hList, 0, &Column);
673
674 ZeroMemory(&Item, sizeof(LV_ITEM));
675
676 do
677 {
678 ClassRet = EnumDeviceClasses(Index,
679 DevName,
680 DevDesc,
681 &DevExist,
682 &DevImage);
683
684 if ((ClassRet != -1) && (DevExist))
685 {
686 Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
687 Item.iItem = Index;
688 Item.iImage = DevImage;
689
690 if (DevDesc[0] != L'\0')
691 Item.pszText = (LPWSTR) DevDesc;
692 else
693 Item.pszText = (LPWSTR) DevName;
694
695 (VOID) ListView_InsertItem(hList, &Item);
696
697 /* Kill InfoList initialized in EnumDeviceClasses */
698 if (hDevInfoTypes)
699 {
700 SetupDiDestroyDeviceInfoList(hDevInfoTypes);
701 hDevInfoTypes = NULL;
702 }
703 }
704 Index++;
705 }
706 while (ClassRet != -1);
707
708 (VOID) ListView_SetImageList(hList, ImageListData.ImageList, LVSIL_SMALL);
709 }
710
711 static INT_PTR CALLBACK
712 HdTypesPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
713 {
714 switch (uMsg)
715 {
716 case WM_INITDIALOG:
717 {
718 InitHardWareTypesPage(hwndDlg);
719 }
720 break;
721
722 case WM_NOTIFY:
723 {
724 LPNMHDR lpnm = (LPNMHDR)lParam;
725
726 switch (lpnm->code)
727 {
728 case PSN_SETACTIVE:
729 {
730 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
731 }
732 break;
733
734 case PSN_WIZBACK:
735 {
736 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SELECTWAYPAGE);
737 return TRUE;
738 }
739 }
740 }
741 break;
742 }
743
744 return FALSE;
745 }
746
747 static INT_PTR CALLBACK
748 ProgressPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
749 {
750 switch (uMsg)
751 {
752 case WM_NOTIFY:
753 {
754 LPNMHDR lpnm = (LPNMHDR)lParam;
755
756 switch (lpnm->code)
757 {
758 case PSN_SETACTIVE:
759 {
760 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
761 }
762 break;
763
764 case PSN_WIZBACK:
765 {
766 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SELECTWAYPAGE);
767 return TRUE;
768 }
769 }
770 }
771 break;
772 }
773
774 return FALSE;
775 }
776
777 static int CALLBACK
778 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
779 {
780 // NOTE: This callback is needed to set large icon correctly.
781 HICON hIcon;
782 switch (uMsg)
783 {
784 case PSCB_INITIALIZED:
785 {
786 hIcon = LoadIconW(hApplet, MAKEINTRESOURCEW(IDI_CPLICON));
787 SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
788 break;
789 }
790 }
791 return 0;
792 }
793
794 static VOID
795 HardwareWizardInit(HWND hwnd)
796 {
797 HPROPSHEETPAGE ahpsp[10];
798 PROPSHEETPAGE psp = {0};
799 PROPSHEETHEADER psh;
800 UINT nPages = 0;
801
802 /* Create the Start page, until setup is working */
803 psp.dwSize = sizeof(PROPSHEETPAGE);
804 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
805 psp.hInstance = hApplet;
806 psp.lParam = 0;
807 psp.pfnDlgProc = StartPageDlgProc;
808 psp.pszTemplate = MAKEINTRESOURCE(IDD_STARTPAGE);
809 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
810
811 /* Create search page */
812 psp.dwSize = sizeof(PROPSHEETPAGE);
813 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
814 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SEARCHTITLE);
815 psp.pszHeaderSubTitle = NULL;
816 psp.hInstance = hApplet;
817 psp.lParam = 0;
818 psp.pfnDlgProc = SearchPageDlgProc;
819 psp.pszTemplate = MAKEINTRESOURCE(IDD_SEARCHPAGE);
820 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
821
822 /* Create is connected page */
823 psp.dwSize = sizeof(PROPSHEETPAGE);
824 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
825 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ISCONNECTED);
826 psp.pszHeaderSubTitle = NULL;
827 psp.hInstance = hApplet;
828 psp.lParam = 0;
829 psp.pfnDlgProc = IsConnectedPageDlgProc;
830 psp.pszTemplate = MAKEINTRESOURCE(IDD_ISCONNECTEDPAGE);
831 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
832
833 /* Create probe list page */
834 psp.dwSize = sizeof(PROPSHEETPAGE);
835 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
836 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROBELISTTITLE);
837 psp.pszHeaderSubTitle = NULL;
838 psp.hInstance = hApplet;
839 psp.lParam = 0;
840 psp.pfnDlgProc = ProbeListPageDlgProc;
841 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROBELISTPAGE);
842 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
843
844 /* Create select search way page */
845 psp.dwSize = sizeof(PROPSHEETPAGE);
846 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
847 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SELECTWAYTITLE);
848 psp.pszHeaderSubTitle = NULL;
849 psp.hInstance = hApplet;
850 psp.lParam = 0;
851 psp.pfnDlgProc = SelectWayPageDlgProc;
852 psp.pszTemplate = MAKEINTRESOURCE(IDD_SELECTWAYPAGE);
853 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
854
855 /* Create device status page */
856 psp.dwSize = sizeof(PROPSHEETPAGE);
857 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
858 psp.hInstance = hApplet;
859 psp.lParam = 0;
860 psp.pfnDlgProc = DevStatusPageDlgProc;
861 psp.pszTemplate = MAKEINTRESOURCE(IDD_HWSTATUSPAGE);
862 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
863
864 /* Create hardware types page */
865 psp.dwSize = sizeof(PROPSHEETPAGE);
866 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
867 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_HDTYPESTITLE);
868 psp.pszHeaderSubTitle = NULL;
869 psp.hInstance = hApplet;
870 psp.lParam = 0;
871 psp.pfnDlgProc = HdTypesPageDlgProc;
872 psp.pszTemplate = MAKEINTRESOURCE(IDD_HWTYPESPAGE);
873 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
874
875 /* Create progress page */
876 psp.dwSize = sizeof(PROPSHEETPAGE);
877 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
878 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SEARCHTITLE);
879 psp.pszHeaderSubTitle = NULL;
880 psp.hInstance = hApplet;
881 psp.lParam = 0;
882 psp.pfnDlgProc = ProgressPageDlgProc;
883 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROGRESSPAGE);
884 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
885
886 /* Create finish page */
887 psp.dwSize = sizeof(PROPSHEETPAGE);
888 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
889 psp.hInstance = hApplet;
890 psp.lParam = 0;
891 psp.pfnDlgProc = FinishPageDlgProc;
892 psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE);
893 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
894
895 /* Create not connected page */
896 psp.dwSize = sizeof(PROPSHEETPAGE);
897 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
898 psp.hInstance = hApplet;
899 psp.lParam = 0;
900 psp.pfnDlgProc = NotConnectedPageDlgProc;
901 psp.pszTemplate = MAKEINTRESOURCE(IDD_NOTCONNECTEDPAGE);
902 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
903
904 /* Create the property sheet */
905 psh.dwSize = sizeof(PROPSHEETHEADER);
906 psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER | PSH_USEICONID | PSH_USECALLBACK;
907 psh.hInstance = hApplet;
908 psh.pszIcon = MAKEINTRESOURCEW(IDI_CPLICON);
909 psh.hwndParent = hwnd;
910 psh.nPages = nPages;
911 psh.nStartPage = 0;
912 psh.phpage = ahpsp;
913 psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
914 psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
915 psh.pfnCallback = PropSheetProc;
916
917 /* Create title font */
918 hTitleFont = CreateTitleFont();
919
920 /* Display the wizard */
921 PropertySheet(&psh);
922
923 DeleteObject(hTitleFont);
924 }
925
926 /* FUNCTIONS ****************************************************************/
927
928 BOOL WINAPI
929 InstallNewDevice(HWND hwndParent, LPGUID ClassGuid, PDWORD pReboot)
930 {
931 return FALSE;
932 }
933
934 VOID WINAPI
935 AddHardwareWizard(HWND hwnd, LPWSTR lpName)
936 {
937 if (lpName != NULL)
938 {
939 DPRINT1("No support of remote installation yet!\n");
940 return;
941 }
942
943 HardwareWizardInit(hwnd);
944 }
945
946 /* Control Panel Callback */
947 LONG CALLBACK
948 CPlApplet(HWND hwndCpl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
949 {
950 switch (uMsg)
951 {
952 case CPL_INIT:
953 return TRUE;
954
955 case CPL_GETCOUNT:
956 return 1;
957
958 case CPL_INQUIRE:
959 {
960 CPLINFO *CPlInfo = (CPLINFO*)lParam2;
961 CPlInfo->lData = 0;
962 CPlInfo->idIcon = IDI_CPLICON;
963 CPlInfo->idName = IDS_CPLNAME;
964 CPlInfo->idInfo = IDS_CPLDESCRIPTION;
965 }
966 break;
967
968 case CPL_DBLCLK:
969 AddHardwareWizard(hwndCpl, NULL);
970 break;
971 }
972
973 return FALSE;
974 }
975
976 BOOL WINAPI
977 DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
978 {
979 UNREFERENCED_PARAMETER(lpvReserved);
980
981 switch (dwReason)
982 {
983 case DLL_PROCESS_ATTACH:
984 hApplet = hinstDLL;
985 hProcessHeap = GetProcessHeap();
986 DisableThreadLibraryCalls(hinstDLL);
987 break;
988 }
989
990 return TRUE;
991 }