2762f31e50c8bc1cfa2acb307b7d34a59f04bc40
[reactos.git] / reactos / 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 _tcscpy(LogFont.lfFaceName, _T("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 IsConnctedPageDlgProc(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 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_NOTCONNECTEDPAGE);
176 else
177 SetWindowLong(hwndDlg, DWL_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 SetWindowLong(hwndDlg, DWL_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 = (LPTSTR) szBuffer;
314 Item.iItem = 0;
315 Item.iImage = -1;
316 (VOID) ListView_InsertItem(hList, &Item);
317
318 (VOID) ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT);
319
320 hDevInfo = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, 0);
321
322 if (hDevInfo == INVALID_HANDLE_VALUE) return;
323
324 /* get the device image List */
325 ImageListData.cbSize = sizeof(ImageListData);
326 SetupDiGetClassImageList(&ImageListData);
327
328 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
329 for (Index = 0; TRUE; Index++)
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 /* Set device name */
382 Item.pszText = (LPWSTR) szBuffer;
383 Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
384 Item.lParam = (LPARAM) pstrStatusText;
385 Item.iItem = (INT) ListView_GetItemCount(hList);
386 (VOID) ListView_InsertItem(hList, &Item);
387
388 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
389 }
390
391 (VOID) ListView_SetImageList(hList, ImageListData.ImageList, LVSIL_SMALL);
392 SetupDiDestroyDeviceInfoList(hDevInfo);
393 }
394
395 static INT_PTR CALLBACK
396 ProbeListPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
397 {
398 INT Index;
399
400 switch (uMsg)
401 {
402 case WM_INITDIALOG:
403 {
404 pDeviceStatusText = (PWSTR)HeapAlloc(hProcessHeap, 0, MAX_STR_SIZE);
405 InitProbeListPage(hwndDlg);
406 }
407 break;
408
409 case WM_COMMAND:
410 {
411
412 }
413 break;
414
415 case WM_NOTIFY:
416 {
417 LPNMHDR lpnm = (LPNMHDR)lParam;
418
419 switch (lpnm->code)
420 {
421 case PSN_SETACTIVE:
422 {
423 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
424 }
425 break;
426
427 case NM_CLICK:
428 {
429 Index = (INT) SendMessage(GetDlgItem(hwndDlg, IDC_PROBELIST), LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
430 if (Index != -1)
431 {
432 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
433 }
434 }
435 break;
436
437 case PSN_WIZNEXT:
438 {
439 Index = (INT) SendMessage(GetDlgItem(hwndDlg, IDC_PROBELIST), LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
440 if (Index != -1)
441 {
442 if (Index == 0)
443 {
444 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_SELECTWAYPAGE);
445 }
446 else
447 {
448 LVITEM Item;
449 PWSTR pts;
450
451 ZeroMemory(&Item, sizeof(LV_ITEM));
452 Item.mask = LVIF_PARAM;
453 Item.iItem = Index;
454 (VOID) ListView_GetItem(GetDlgItem(hwndDlg, IDC_PROBELIST), &Item);
455 pts = (PWSTR) Item.lParam;
456 wcscpy(pDeviceStatusText, pts);
457
458 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_HWSTATUSPAGE);
459 }
460 }
461 return TRUE;
462 }
463 }
464 }
465 break;
466
467 case WM_DESTROY:
468 {
469 INT Index;
470 LVITEM Item;
471
472 for (Index = ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_PROBELIST)); --Index > 0;)
473 {
474 ZeroMemory(&Item, sizeof(LV_ITEM));
475 Item.mask = LVIF_PARAM;
476 Item.iItem = Index;
477 (VOID) ListView_GetItem(GetDlgItem(hwndDlg, IDC_PROBELIST), &Item);
478 HeapFree(hProcessHeap, 0, (LPVOID) Item.lParam);
479 }
480 HeapFree(hProcessHeap, 0, (LPVOID) pDeviceStatusText);
481 }
482 break;
483 }
484
485 return FALSE;
486 }
487
488 static INT_PTR CALLBACK
489 SelectWayPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
490 {
491 switch (uMsg)
492 {
493 case WM_NOTIFY:
494 {
495 LPNMHDR lpnm = (LPNMHDR)lParam;
496
497 switch (lpnm->code)
498 {
499 case PSN_SETACTIVE:
500 {
501 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK);
502 if (SendDlgItemMessage(hwndDlg, IDC_AUTOINSTALL, BM_GETCHECK, 0, 0) == BST_CHECKED)
503 SendDlgItemMessage(hwndDlg, IDC_MANUALLYINST, BM_SETCHECK, 0, 0);
504 else
505 {
506 SendDlgItemMessage(hwndDlg, IDC_AUTOINSTALL, BM_SETCHECK, 1, 1);
507 SendDlgItemMessage(hwndDlg, IDC_MANUALLYINST, BM_SETCHECK, 0, 0);
508 }
509 }
510 break;
511
512 case PSN_WIZNEXT:
513 {
514 if (SendDlgItemMessage(hwndDlg, IDC_AUTOINSTALL, BM_GETCHECK, 0, 0) == BST_CHECKED)
515 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_PROGRESSPAGE);
516 else
517 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_HWTYPESPAGE);
518
519 return TRUE;
520 }
521 }
522 }
523 break;
524 }
525
526 return FALSE;
527 }
528
529 static INT_PTR CALLBACK
530 DevStatusPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
531 {
532 switch (uMsg)
533 {
534 case WM_INITDIALOG:
535 {
536 /* Set title font */
537 SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE);
538 /* Set status text */
539 SetWindowText(GetDlgItem(hwndDlg, IDC_HWSTATUSEDIT), pDeviceStatusText);
540 }
541 break;
542
543 case WM_NOTIFY:
544 {
545 LPNMHDR lpnm = (LPNMHDR)lParam;
546
547 switch (lpnm->code)
548 {
549 case PSN_SETACTIVE:
550 {
551 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH | PSWIZB_BACK);
552 }
553 break;
554
555 case PSN_WIZBACK:
556 {
557 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_PROBELISTPAGE);
558 return TRUE;
559 }
560 }
561 }
562 break;
563 }
564
565 return FALSE;
566 }
567
568 static INT
569 EnumDeviceClasses(INT ClassIndex,
570 LPWSTR DevClassName,
571 LPWSTR DevClassDesc,
572 BOOL *DevPresent,
573 INT *ClassImage)
574 {
575 GUID ClassGuid;
576 HKEY KeyClass;
577 WCHAR ClassName[MAX_STR_SIZE];
578 DWORD RequiredSize = MAX_STR_SIZE;
579 UINT Ret;
580
581 *DevPresent = FALSE;
582 *DevClassName = L'\0';
583
584 Ret = CM_Enumerate_Classes(ClassIndex,
585 &ClassGuid,
586 0);
587 if (Ret != CR_SUCCESS)
588 {
589 /* all classes enumerated */
590 if(Ret == CR_NO_SUCH_VALUE)
591 {
592 hDevInfoTypes = NULL;
593 return -1;
594 }
595
596 if (Ret == CR_INVALID_DATA)
597 {
598 ; /*FIXME: what should we do here? */
599 }
600
601 /* handle other errors... */
602 }
603
604 if (SetupDiClassNameFromGuid(&ClassGuid,
605 ClassName,
606 RequiredSize,
607 &RequiredSize))
608 {
609 lstrcpy(DevClassName, ClassName);
610 }
611
612 if (!SetupDiGetClassImageIndex(&ImageListData,
613 &ClassGuid,
614 ClassImage))
615 {
616 /* FIXME: can we do this?
617 * Set the blank icon: IDI_SETUPAPI_BLANK = 41
618 * it'll be image 24 in the imagelist */
619 *ClassImage = 24;
620 }
621
622 /* Get device info for all devices of a particular class */
623 hDevInfoTypes = SetupDiGetClassDevs(&ClassGuid,
624 NULL,
625 NULL,
626 DIGCF_PRESENT);
627 if (hDevInfoTypes == INVALID_HANDLE_VALUE)
628 {
629 hDevInfoTypes = NULL;
630 return 0;
631 }
632
633 KeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid,
634 MAXIMUM_ALLOWED,
635 DIOCR_INSTALLER,
636 NULL,
637 0);
638 if (KeyClass != INVALID_HANDLE_VALUE)
639 {
640
641 LONG dwSize = MAX_STR_SIZE;
642
643 if (RegQueryValue(KeyClass,
644 NULL,
645 DevClassDesc,
646 &dwSize) != ERROR_SUCCESS)
647 {
648 *DevClassDesc = L'\0';
649 }
650 }
651 else
652 {
653 return -3;
654 }
655
656 *DevPresent = TRUE;
657
658 RegCloseKey(KeyClass);
659
660 return 0;
661 }
662
663 static VOID
664 InitHardWareTypesPage(HWND hwndDlg)
665 {
666 HWND hList = GetDlgItem(hwndDlg, IDC_HWTYPESLIST);
667 WCHAR DevName[MAX_STR_SIZE];
668 WCHAR DevDesc[MAX_STR_SIZE];
669 BOOL DevExist = FALSE;
670 INT ClassRet, DevImage, Index = 0;
671 LV_COLUMN Column;
672 LV_ITEM Item;
673 RECT Rect;
674
675 if (!hList) return;
676
677 ZeroMemory(&Column, sizeof(LV_COLUMN));
678
679 GetClientRect(hList, &Rect);
680
681 Column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
682 Column.fmt = LVCFMT_LEFT;
683 Column.iSubItem = 0;
684 Column.pszText = NULL;
685 Column.cx = Rect.right - GetSystemMetrics(SM_CXVSCROLL);
686 (VOID) ListView_InsertColumn(hList, 0, &Column);
687
688 ZeroMemory(&Item, sizeof(LV_ITEM));
689
690 do
691 {
692 ClassRet = EnumDeviceClasses(Index,
693 DevName,
694 DevDesc,
695 &DevExist,
696 &DevImage);
697
698 if ((ClassRet != -1) && (DevExist))
699 {
700 Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
701 Item.iItem = Index;
702 Item.iImage = DevImage;
703
704 if (DevDesc[0] != L'\0')
705 Item.pszText = (LPWSTR) DevDesc;
706 else
707 Item.pszText = (LPWSTR) DevName;
708
709 (VOID) ListView_InsertItem(hList, &Item);
710
711 /* kill InfoList initialized in EnumDeviceClasses */
712 if (hDevInfoTypes)
713 {
714 SetupDiDestroyDeviceInfoList(hDevInfoTypes);
715 hDevInfoTypes = NULL;
716 }
717 }
718 Index++;
719 }
720 while (ClassRet != -1);
721
722 (VOID) ListView_SetImageList(hList, ImageListData.ImageList, LVSIL_SMALL);
723 }
724
725 static INT_PTR CALLBACK
726 HdTypesPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
727 {
728 switch (uMsg)
729 {
730 case WM_INITDIALOG:
731 {
732 InitHardWareTypesPage(hwndDlg);
733 }
734 break;
735
736 case WM_NOTIFY:
737 {
738 LPNMHDR lpnm = (LPNMHDR)lParam;
739
740 switch (lpnm->code)
741 {
742 case PSN_SETACTIVE:
743 {
744 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
745 }
746 break;
747
748 case PSN_WIZBACK:
749 {
750 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_SELECTWAYPAGE);
751 return TRUE;
752 }
753 }
754 }
755 break;
756 }
757
758 return FALSE;
759 }
760
761 static INT_PTR CALLBACK
762 ProgressPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
763 {
764 switch (uMsg)
765 {
766 case WM_NOTIFY:
767 {
768 LPNMHDR lpnm = (LPNMHDR)lParam;
769
770 switch (lpnm->code)
771 {
772 case PSN_SETACTIVE:
773 {
774 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
775 }
776 break;
777
778 case PSN_WIZBACK:
779 {
780 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_SELECTWAYPAGE);
781 return TRUE;
782 }
783 }
784 }
785 break;
786 }
787
788 return FALSE;
789 }
790
791 static VOID
792 HardwareWizardInit(HWND hwnd)
793 {
794 HPROPSHEETPAGE ahpsp[10];
795 PROPSHEETPAGE psp = {0};
796 PROPSHEETHEADER psh;
797 UINT nPages = 0;
798
799 /* Create the Start page, until setup is working */
800 psp.dwSize = sizeof(PROPSHEETPAGE);
801 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
802 psp.hInstance = hApplet;
803 psp.lParam = 0;
804 psp.pfnDlgProc = StartPageDlgProc;
805 psp.pszTemplate = MAKEINTRESOURCE(IDD_STARTPAGE);
806 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
807
808 /* Create search page */
809 psp.dwSize = sizeof(PROPSHEETPAGE);
810 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
811 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SEARCHTITLE);
812 psp.pszHeaderSubTitle = NULL;
813 psp.hInstance = hApplet;
814 psp.lParam = 0;
815 psp.pfnDlgProc = SearchPageDlgProc;
816 psp.pszTemplate = MAKEINTRESOURCE(IDD_SEARCHPAGE);
817 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
818
819 /* Create is connected page */
820 psp.dwSize = sizeof(PROPSHEETPAGE);
821 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
822 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ISCONNECTED);
823 psp.pszHeaderSubTitle = NULL;
824 psp.hInstance = hApplet;
825 psp.lParam = 0;
826 psp.pfnDlgProc = IsConnctedPageDlgProc;
827 psp.pszTemplate = MAKEINTRESOURCE(IDD_ISCONNECTEDPAGE);
828 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
829
830 /* Create probe list page */
831 psp.dwSize = sizeof(PROPSHEETPAGE);
832 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
833 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROBELISTTITLE);
834 psp.pszHeaderSubTitle = NULL;
835 psp.hInstance = hApplet;
836 psp.lParam = 0;
837 psp.pfnDlgProc = ProbeListPageDlgProc;
838 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROBELISTPAGE);
839 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
840
841 /* Create select search way page */
842 psp.dwSize = sizeof(PROPSHEETPAGE);
843 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
844 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SELECTWAYTITLE);
845 psp.pszHeaderSubTitle = NULL;
846 psp.hInstance = hApplet;
847 psp.lParam = 0;
848 psp.pfnDlgProc = SelectWayPageDlgProc;
849 psp.pszTemplate = MAKEINTRESOURCE(IDD_SELECTWAYPAGE);
850 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
851
852 /* Create device status page */
853 psp.dwSize = sizeof(PROPSHEETPAGE);
854 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
855 psp.hInstance = hApplet;
856 psp.lParam = 0;
857 psp.pfnDlgProc = DevStatusPageDlgProc;
858 psp.pszTemplate = MAKEINTRESOURCE(IDD_HWSTATUSPAGE);
859 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
860
861 /* Create hardware types page */
862 psp.dwSize = sizeof(PROPSHEETPAGE);
863 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
864 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_HDTYPESTITLE);
865 psp.pszHeaderSubTitle = NULL;
866 psp.hInstance = hApplet;
867 psp.lParam = 0;
868 psp.pfnDlgProc = HdTypesPageDlgProc;
869 psp.pszTemplate = MAKEINTRESOURCE(IDD_HWTYPESPAGE);
870 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
871
872 /* Create progress page */
873 psp.dwSize = sizeof(PROPSHEETPAGE);
874 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
875 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SEARCHTITLE);
876 psp.pszHeaderSubTitle = NULL;
877 psp.hInstance = hApplet;
878 psp.lParam = 0;
879 psp.pfnDlgProc = ProgressPageDlgProc;
880 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROGRESSPAGE);
881 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
882
883 /* Create finish page */
884 psp.dwSize = sizeof(PROPSHEETPAGE);
885 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
886 psp.hInstance = hApplet;
887 psp.lParam = 0;
888 psp.pfnDlgProc = FinishPageDlgProc;
889 psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE);
890 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
891
892 /* Create not connected page */
893 psp.dwSize = sizeof(PROPSHEETPAGE);
894 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
895 psp.hInstance = hApplet;
896 psp.lParam = 0;
897 psp.pfnDlgProc = NotConnectedPageDlgProc;
898 psp.pszTemplate = MAKEINTRESOURCE(IDD_NOTCONNECTEDPAGE);
899 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
900
901 /* Create the property sheet */
902 psh.dwSize = sizeof(PROPSHEETHEADER);
903 psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
904 psh.hInstance = hApplet;
905 psh.hwndParent = hwnd;
906 psh.nPages = nPages;
907 psh.nStartPage = 0;
908 psh.phpage = ahpsp;
909 psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
910 psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
911
912 /* Create title font */
913 hTitleFont = CreateTitleFont();
914
915 /* Display the wizard */
916 PropertySheet(&psh);
917
918 DeleteObject(hTitleFont);
919 }
920
921 /* FUNCTIONS ****************************************************************/
922
923 BOOL WINAPI
924 InstallNewDevice(HWND hwndParent, LPGUID ClassGuid, PDWORD pReboot)
925 {
926 return FALSE;
927 }
928
929 VOID WINAPI
930 AddHardwareWizard(HWND hwnd, LPWSTR lpName)
931 {
932 if (lpName != NULL)
933 {
934 DPRINT1("No support of remote installation yet!\n");
935 return;
936 }
937
938 HardwareWizardInit(hwnd);
939 }
940
941 /* Control Panel Callback */
942 LONG CALLBACK
943 CPlApplet(HWND hwndCpl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
944 {
945 switch (uMsg)
946 {
947 case CPL_INIT:
948 return TRUE;
949
950 case CPL_GETCOUNT:
951 return 1;
952
953 case CPL_INQUIRE:
954 {
955 CPLINFO *CPlInfo = (CPLINFO*)lParam2;
956 CPlInfo->lData = 0;
957 CPlInfo->idIcon = IDI_CPLICON;
958 CPlInfo->idName = IDS_CPLNAME;
959 CPlInfo->idInfo = IDS_CPLDESCRIPTION;
960 }
961 break;
962
963 case CPL_DBLCLK:
964 AddHardwareWizard(hwndCpl, NULL);
965 break;
966 }
967
968 return FALSE;
969 }
970
971 BOOL WINAPI
972 DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
973 {
974 UNREFERENCED_PARAMETER(lpvReserved);
975
976 switch (dwReason)
977 {
978 case DLL_PROCESS_ATTACH:
979 hApplet = hinstDLL;
980 hProcessHeap = GetProcessHeap();
981 DisableThreadLibraryCalls(hinstDLL);
982 break;
983 }
984
985 return TRUE;
986 }