2 * ReactOS New devices installation
3 * Copyright (C) 2005, 2008 ReactOS Team
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.
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.
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
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)
30 /* GLOBALS ******************************************************************/
32 HINSTANCE hApplet
= NULL
;
34 SP_CLASSIMAGELIST_DATA ImageListData
;
35 PWSTR pDeviceStatusText
;
38 typedef BOOL (WINAPI
*PINSTALL_NEW_DEVICE
)(HWND
, LPGUID
, PDWORD
);
41 /* STATIC FUNCTIONS *********************************************************/
52 ncm
.cbSize
= sizeof(NONCLIENTMETRICS
);
53 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
55 LogFont
= ncm
.lfMessageFont
;
56 LogFont
.lfWeight
= FW_BOLD
;
57 _tcscpy(LogFont
.lfFaceName
, _T("MS Shell Dlg"));
61 LogFont
.lfHeight
= 0 - GetDeviceCaps (hdc
, LOGPIXELSY
) * FontSize
/ 72;
62 hFont
= CreateFontIndirect(&LogFont
);
68 static INT_PTR CALLBACK
69 StartPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
76 SendDlgItemMessage(hwndDlg
, IDC_FINISHTITLE
, WM_SETFONT
, (WPARAM
)hTitleFont
, (LPARAM
)TRUE
);
82 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
88 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
99 static INT_PTR CALLBACK
100 SearchPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
106 /* TODO: PnP devices search */
112 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
118 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
129 static INT_PTR CALLBACK
130 IsConnctedPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
136 if(HIWORD(wParam
) == BN_CLICKED
)
138 if ((SendDlgItemMessage(hwndDlg
, IDC_CONNECTED
, BM_GETCHECK
, 0, 0) == BST_CHECKED
) ||
139 (SendDlgItemMessage(hwndDlg
, IDC_NOTCONNECTED
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
141 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
145 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
);
153 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
159 if ((SendDlgItemMessage(hwndDlg
, IDC_CONNECTED
, BM_GETCHECK
, 0, 0) == BST_CHECKED
) ||
160 (SendDlgItemMessage(hwndDlg
, IDC_NOTCONNECTED
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
162 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
166 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
);
173 if (SendDlgItemMessage(hwndDlg
, IDC_NOTCONNECTED
, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
174 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, IDD_NOTCONNECTEDPAGE
);
176 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, IDD_PROBELISTPAGE
);
188 static INT_PTR CALLBACK
189 FinishPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
196 SendDlgItemMessage(hwndDlg
, IDC_FINISHTITLE
, WM_SETFONT
, (WPARAM
)hTitleFont
, (LPARAM
)TRUE
);
202 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
208 /* Only "Finish" button */
209 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
220 static INT_PTR CALLBACK
221 NotConnectedPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
228 SendDlgItemMessage(hwndDlg
, IDC_FINISHTITLE
, WM_SETFONT
, (WPARAM
)hTitleFont
, (LPARAM
)TRUE
);
234 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
240 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
| PSWIZB_BACK
);
246 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, IDD_ISCONNECTEDPAGE
);
258 TrimGuidString(LPWSTR szString
, LPWSTR szNewString
)
263 if (wcslen(szString
) == 38)
265 if ((szString
[0] == L
'{') && (szString
[37] == L
'}'))
267 for (Index
= 0; Index
< wcslen(szString
); Index
++)
268 szBuffer
[Index
] = szString
[Index
+ 1];
270 szBuffer
[36] = L
'\0';
271 wcscpy(szNewString
, szBuffer
);
275 wcscpy(szNewString
, L
"\0");
279 InitProbeListPage(HWND hwndDlg
)
283 WCHAR szBuffer
[MAX_STR_SIZE
], szGuid
[MAX_STR_SIZE
],
284 szTrimGuid
[MAX_STR_SIZE
], szStatusText
[MAX_STR_SIZE
];
285 HWND hList
= GetDlgItem(hwndDlg
, IDC_PROBELIST
);
286 PWSTR pstrStatusText
;
288 SP_DEVINFO_DATA DevInfoData
;
289 ULONG ulStatus
, ulProblemNumber
;
296 ZeroMemory(&Column
, sizeof(LV_COLUMN
));
298 GetClientRect(hList
, &Rect
);
300 Column
.mask
= LVCF_FMT
| LVCF_TEXT
| LVCF_WIDTH
;
301 Column
.fmt
= LVCFMT_LEFT
;
303 Column
.pszText
= NULL
;
304 Column
.cx
= Rect
.right
- GetSystemMetrics(SM_CXVSCROLL
);
305 (VOID
) ListView_InsertColumn(hList
, 0, &Column
);
307 ZeroMemory(&Item
, sizeof(LV_ITEM
));
309 LoadString(hApplet
, IDS_ADDNEWDEVICE
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
));
311 Item
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
312 Item
.pszText
= (LPTSTR
) szBuffer
;
315 (VOID
) ListView_InsertItem(hList
, &Item
);
317 (VOID
) ListView_SetExtendedListViewStyle(hList
, LVS_EX_FULLROWSELECT
);
319 hDevInfo
= SetupDiGetClassDevsEx(NULL
, NULL
, NULL
, DIGCF_ALLCLASSES
| DIGCF_PRESENT
, NULL
, NULL
, 0);
321 if (hDevInfo
== INVALID_HANDLE_VALUE
) return;
323 /* get the device image List */
324 ImageListData
.cbSize
= sizeof(ImageListData
);
325 SetupDiGetClassImageList(&ImageListData
);
327 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
328 for (Index
= 0; TRUE
; Index
++)
330 if (!SetupDiEnumDeviceInfo(hDevInfo
, Index
, &DevInfoData
)) break;
332 if (CM_Get_DevNode_Status_Ex(&ulStatus
, &ulProblemNumber
, DevInfoData
.DevInst
, 0, NULL
) == CR_SUCCESS
)
334 if (ulStatus
& DN_NO_SHOW_IN_DM
) continue;
337 /* get the device's friendly name */
338 if (!SetupDiGetDeviceRegistryProperty(hDevInfo
,
346 /* if the friendly name fails, try the description instead */
347 SetupDiGetDeviceRegistryProperty(hDevInfo
,
356 SetupDiGetDeviceRegistryProperty(hDevInfo
,
364 TrimGuidString(szGuid
, szTrimGuid
);
365 UuidFromStringW(szTrimGuid
, &ClassGuid
);
367 SetupDiGetClassImageIndex(&ImageListData
,
371 DeviceProblemTextW(NULL
,
375 sizeof(szStatusText
) / sizeof(WCHAR
));
377 pstrStatusText
= (PWSTR
)HeapAlloc(hProcessHeap
, 0, sizeof(szStatusText
));
378 lstrcpy(pstrStatusText
, szStatusText
);
380 /* Set device name */
381 Item
.pszText
= (LPWSTR
) szBuffer
;
382 Item
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_IMAGE
;
383 Item
.lParam
= (LPARAM
) pstrStatusText
;
384 Item
.iItem
= (INT
) ListView_GetItemCount(hList
);
385 (VOID
) ListView_InsertItem(hList
, &Item
);
387 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
390 (VOID
) ListView_SetImageList(hList
, ImageListData
.ImageList
, LVSIL_SMALL
);
391 SetupDiDestroyDeviceInfoList(hDevInfo
);
394 static INT_PTR CALLBACK
395 ProbeListPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
403 pDeviceStatusText
= (PWSTR
)HeapAlloc(hProcessHeap
, 0, MAX_STR_SIZE
);
404 InitProbeListPage(hwndDlg
);
416 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
422 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
);
428 Index
= (INT
) SendMessage(GetDlgItem(hwndDlg
, IDC_PROBELIST
), LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
431 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
438 Index
= (INT
) SendMessage(GetDlgItem(hwndDlg
, IDC_PROBELIST
), LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
443 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, IDD_SELECTWAYPAGE
);
450 ZeroMemory(&Item
, sizeof(LV_ITEM
));
451 Item
.mask
= LVIF_PARAM
;
453 (VOID
) ListView_GetItem(GetDlgItem(hwndDlg
, IDC_PROBELIST
), &Item
);
454 pts
= (PWSTR
) Item
.lParam
;
455 wcscpy(pDeviceStatusText
, pts
);
457 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, IDD_HWSTATUSPAGE
);
471 for (Index
= ListView_GetItemCount(GetDlgItem(hwndDlg
, IDC_PROBELIST
)); --Index
> 0;)
473 ZeroMemory(&Item
, sizeof(LV_ITEM
));
474 Item
.mask
= LVIF_PARAM
;
476 (VOID
) ListView_GetItem(GetDlgItem(hwndDlg
, IDC_PROBELIST
), &Item
);
477 HeapFree(hProcessHeap
, 0, (LPVOID
) Item
.lParam
);
479 HeapFree(hProcessHeap
, 0, (LPVOID
) pDeviceStatusText
);
487 static INT_PTR CALLBACK
488 SelectWayPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
494 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
500 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
501 SendDlgItemMessage(hwndDlg
, IDC_AUTOINSTALL
, BM_SETCHECK
, 1, 1);
507 if (SendDlgItemMessage(hwndDlg
, IDC_AUTOINSTALL
, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
508 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, IDD_PROGRESSPAGE
);
510 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, IDD_HWTYPESPAGE
);
522 static INT_PTR CALLBACK
523 DevStatusPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
530 SendDlgItemMessage(hwndDlg
, IDC_FINISHTITLE
, WM_SETFONT
, (WPARAM
)hTitleFont
, (LPARAM
)TRUE
);
531 /* Set status text */
532 SetWindowText(GetDlgItem(hwndDlg
, IDC_HWSTATUSEDIT
), pDeviceStatusText
);
538 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
544 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
| PSWIZB_BACK
);
550 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, IDD_PROBELISTPAGE
);
561 static INT_PTR CALLBACK
562 HdTypesPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
568 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
574 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
);
580 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, IDD_SELECTWAYPAGE
);
591 static INT_PTR CALLBACK
592 ProgressPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
598 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
604 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
);
610 SetWindowLong(hwndDlg
, DWL_MSGRESULT
, IDD_SELECTWAYPAGE
);
622 HardwareWizardInit(HWND hwnd
)
624 HPROPSHEETPAGE ahpsp
[10];
625 PROPSHEETPAGE psp
= {0};
629 /* Create the Start page, until setup is working */
630 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
631 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
632 psp
.hInstance
= hApplet
;
634 psp
.pfnDlgProc
= StartPageDlgProc
;
635 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_STARTPAGE
);
636 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
638 /* Create search page */
639 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
640 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
641 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_SEARCHTITLE
);
642 psp
.pszHeaderSubTitle
= NULL
;
643 psp
.hInstance
= hApplet
;
645 psp
.pfnDlgProc
= SearchPageDlgProc
;
646 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SEARCHPAGE
);
647 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
649 /* Create is connected page */
650 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
651 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
652 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_ISCONNECTED
);
653 psp
.pszHeaderSubTitle
= NULL
;
654 psp
.hInstance
= hApplet
;
656 psp
.pfnDlgProc
= IsConnctedPageDlgProc
;
657 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_ISCONNECTEDPAGE
);
658 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
660 /* Create probe list page */
661 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
662 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
663 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PROBELISTTITLE
);
664 psp
.pszHeaderSubTitle
= NULL
;
665 psp
.hInstance
= hApplet
;
667 psp
.pfnDlgProc
= ProbeListPageDlgProc
;
668 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROBELISTPAGE
);
669 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
671 /* Create select search way page */
672 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
673 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
674 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_SELECTWAYTITLE
);
675 psp
.pszHeaderSubTitle
= NULL
;
676 psp
.hInstance
= hApplet
;
678 psp
.pfnDlgProc
= SelectWayPageDlgProc
;
679 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SELECTWAYPAGE
);
680 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
682 /* Create device status page */
683 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
684 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
685 psp
.hInstance
= hApplet
;
687 psp
.pfnDlgProc
= DevStatusPageDlgProc
;
688 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_HWSTATUSPAGE
);
689 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
691 /* Create hardware types page */
692 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
693 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
694 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_HDTYPESTITLE
);
695 psp
.pszHeaderSubTitle
= NULL
;
696 psp
.hInstance
= hApplet
;
698 psp
.pfnDlgProc
= HdTypesPageDlgProc
;
699 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_HWTYPESPAGE
);
700 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
702 /* Create progress page */
703 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
704 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
705 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_SEARCHTITLE
);
706 psp
.pszHeaderSubTitle
= NULL
;
707 psp
.hInstance
= hApplet
;
709 psp
.pfnDlgProc
= ProgressPageDlgProc
;
710 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROGRESSPAGE
);
711 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
713 /* Create finish page */
714 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
715 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
716 psp
.hInstance
= hApplet
;
718 psp
.pfnDlgProc
= FinishPageDlgProc
;
719 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
720 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
722 /* Create not connected page */
723 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
724 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
725 psp
.hInstance
= hApplet
;
727 psp
.pfnDlgProc
= NotConnectedPageDlgProc
;
728 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_NOTCONNECTEDPAGE
);
729 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
731 /* Create the property sheet */
732 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
733 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
;
734 psh
.hInstance
= hApplet
;
735 psh
.hwndParent
= hwnd
;
739 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
740 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
742 /* Create title font */
743 hTitleFont
= CreateTitleFont();
745 /* Display the wizard */
748 DeleteObject(hTitleFont
);
751 /* FUNCTIONS ****************************************************************/
754 InstallNewDevice(HWND hwndParent
, LPGUID ClassGuid
, PDWORD pReboot
)
760 AddHardwareWizard(HWND hwnd
, LPWSTR lpName
)
764 DPRINT1("No support of remote installation yet!\n");
768 HardwareWizardInit(hwnd
);
771 /* Control Panel Callback */
773 CPlApplet(HWND hwndCpl
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
785 CPLINFO
*CPlInfo
= (CPLINFO
*)lParam2
;
787 CPlInfo
->idIcon
= IDI_CPLICON
;
788 CPlInfo
->idName
= IDS_CPLNAME
;
789 CPlInfo
->idInfo
= IDS_CPLDESCRIPTION
;
794 AddHardwareWizard(hwndCpl
, NULL
);
802 DllMain(HINSTANCE hinstDLL
, DWORD dwReason
, LPVOID lpvReserved
)
804 UNREFERENCED_PARAMETER(lpvReserved
);
808 case DLL_PROCESS_ATTACH
:
810 hProcessHeap
= GetProcessHeap();
811 DisableThreadLibraryCalls(hinstDLL
);