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