/* * ReactOS New devices installation * Copyright (C) 2005, 2008 ReactOS Team * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * PROJECT: ReactOS Add hardware control panel * FILE: dll/cpl/hdwwiz/hdwwiz.c * PURPOSE: ReactOS Add hardware control panel * PROGRAMMER: Hervé Poussineau (hpoussin@reactos.org) * Dmitry Chapyshev (dmitry@reactos.org) */ #include "resource.h" #include "hdwwiz.h" /* GLOBALS ******************************************************************/ HINSTANCE hApplet = NULL; HFONT hTitleFont; SP_CLASSIMAGELIST_DATA ImageListData; PWSTR pDeviceStatusText; HANDLE hProcessHeap; HDEVINFO hDevInfoTypes; typedef BOOL (WINAPI *PINSTALL_NEW_DEVICE)(HWND, LPGUID, PDWORD); /* STATIC FUNCTIONS *********************************************************/ static HFONT CreateTitleFont(VOID) { NONCLIENTMETRICS ncm; LOGFONT LogFont; HDC hdc; INT FontSize; HFONT hFont; ncm.cbSize = sizeof(NONCLIENTMETRICS); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); LogFont = ncm.lfMessageFont; LogFont.lfWeight = FW_BOLD; wcscpy(LogFont.lfFaceName, L"MS Shell Dlg"); hdc = GetDC(NULL); FontSize = 12; LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72; hFont = CreateFontIndirect(&LogFont); ReleaseDC(NULL, hdc); return hFont; } static INT_PTR CALLBACK StartPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { /* Set title font */ SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE); } break; case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam; switch (lpnm->code) { case PSN_SETACTIVE: { PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT); } break; } } break; } return FALSE; } static INT_PTR CALLBACK SearchPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { /* TODO: PnP devices search */ } break; case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam; switch (lpnm->code) { case PSN_SETACTIVE: { PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); } break; } } break; } return FALSE; } static INT_PTR CALLBACK IsConnectedPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_COMMAND: { if(HIWORD(wParam) == BN_CLICKED) { if ((SendDlgItemMessage(hwndDlg, IDC_CONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED) || (SendDlgItemMessage(hwndDlg, IDC_NOTCONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED)) { PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); } else { PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK); } } } break; case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam; switch (lpnm->code) { case PSN_SETACTIVE: { if ((SendDlgItemMessage(hwndDlg, IDC_CONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED) || (SendDlgItemMessage(hwndDlg, IDC_NOTCONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED)) { PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); } else { PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK); } } break; case PSN_WIZNEXT: { if (SendDlgItemMessage(hwndDlg, IDC_NOTCONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED) SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NOTCONNECTEDPAGE); else SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PROBELISTPAGE); return TRUE; } } } break; } return FALSE; } static INT_PTR CALLBACK FinishPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { /* Set title font */ SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE); } break; case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam; switch (lpnm->code) { case PSN_SETACTIVE: { /* Only "Finish" button */ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH); } break; } } break; } return FALSE; } static INT_PTR CALLBACK NotConnectedPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { /* Set title font */ SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE); } break; case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam; switch (lpnm->code) { case PSN_SETACTIVE: { PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH | PSWIZB_BACK); } break; case PSN_WIZBACK: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_ISCONNECTEDPAGE); return TRUE; } } } break; } return FALSE; } static VOID TrimGuidString(LPWSTR szString, LPWSTR szNewString) { WCHAR szBuffer[39]; INT Index; if (wcslen(szString) == 38) { if ((szString[0] == L'{') && (szString[37] == L'}')) { for (Index = 0; Index < wcslen(szString); Index++) szBuffer[Index] = szString[Index + 1]; szBuffer[36] = L'\0'; wcscpy(szNewString, szBuffer); return; } } wcscpy(szNewString, L"\0"); } static VOID InitProbeListPage(HWND hwndDlg) { LV_COLUMN Column; LV_ITEM Item; WCHAR szBuffer[MAX_STR_SIZE], szGuid[MAX_STR_SIZE], szTrimGuid[MAX_STR_SIZE], szStatusText[MAX_STR_SIZE]; HWND hList = GetDlgItem(hwndDlg, IDC_PROBELIST); PWSTR pstrStatusText; HDEVINFO hDevInfo; SP_DEVINFO_DATA DevInfoData; ULONG ulStatus, ulProblemNumber; GUID ClassGuid; RECT Rect; DWORD Index; if (!hList) return; ZeroMemory(&Column, sizeof(LV_COLUMN)); GetClientRect(hList, &Rect); Column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; Column.fmt = LVCFMT_LEFT; Column.iSubItem = 0; Column.pszText = NULL; Column.cx = Rect.right - GetSystemMetrics(SM_CXVSCROLL); (VOID) ListView_InsertColumn(hList, 0, &Column); ZeroMemory(&Item, sizeof(LV_ITEM)); LoadString(hApplet, IDS_ADDNEWDEVICE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)); Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; Item.pszText = (LPWSTR) szBuffer; Item.iItem = (INT) ListView_GetItemCount(hList); Item.iImage = -1; (VOID) ListView_InsertItem(hList, &Item); hDevInfo = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, 0); if (hDevInfo == INVALID_HANDLE_VALUE) return; /* Get the device image List */ ImageListData.cbSize = sizeof(ImageListData); SetupDiGetClassImageList(&ImageListData); DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (Index = 0; TRUE; Index++) { szBuffer[0] = L'\0'; if (!SetupDiEnumDeviceInfo(hDevInfo, Index, &DevInfoData)) break; if (CM_Get_DevNode_Status_Ex(&ulStatus, &ulProblemNumber, DevInfoData.DevInst, 0, NULL) == CR_SUCCESS) { if (ulStatus & DN_NO_SHOW_IN_DM) continue; } /* Get the device's friendly name */ if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DevInfoData, SPDRP_FRIENDLYNAME, 0, (BYTE*)szBuffer, MAX_STR_SIZE, NULL)) { /* If the friendly name fails, try the description instead */ SetupDiGetDeviceRegistryProperty(hDevInfo, &DevInfoData, SPDRP_DEVICEDESC, 0, (BYTE*)szBuffer, MAX_STR_SIZE, NULL); } SetupDiGetDeviceRegistryProperty(hDevInfo, &DevInfoData, SPDRP_CLASSGUID, 0, (BYTE*)szGuid, MAX_STR_SIZE, NULL); TrimGuidString(szGuid, szTrimGuid); UuidFromStringW(szTrimGuid, &ClassGuid); SetupDiGetClassImageIndex(&ImageListData, &ClassGuid, &Item.iImage); DeviceProblemTextW(NULL, DevInfoData.DevInst, ulProblemNumber, szStatusText, sizeof(szStatusText) / sizeof(WCHAR)); pstrStatusText = (PWSTR)HeapAlloc(hProcessHeap, 0, sizeof(szStatusText)); lstrcpy(pstrStatusText, szStatusText); if (szBuffer[0] != L'\0') { /* Set device name */ Item.pszText = (LPWSTR) szBuffer; Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; Item.lParam = (LPARAM) pstrStatusText; Item.iItem = (INT) ListView_GetItemCount(hList); (VOID) ListView_InsertItem(hList, &Item); } DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); } (VOID) ListView_SetImageList(hList, ImageListData.ImageList, LVSIL_SMALL); (VOID) ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT); SetupDiDestroyDeviceInfoList(hDevInfo); } static INT_PTR CALLBACK ProbeListPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { INT Index; LVITEM Item; switch (uMsg) { case WM_INITDIALOG: { pDeviceStatusText = (PWSTR)HeapAlloc(hProcessHeap, 0, MAX_STR_SIZE); InitProbeListPage(hwndDlg); } break; case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam; switch (lpnm->code) { case PSN_SETACTIVE: { PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT); } break; case PSN_WIZNEXT: { Index = (INT) SendMessage(GetDlgItem(hwndDlg, IDC_PROBELIST), LVM_GETNEXTITEM, -1, LVNI_FOCUSED); if (Index == -1) Index = 0; if (Index == 0) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SELECTWAYPAGE); } else { PWSTR pts; ZeroMemory(&Item, sizeof(LV_ITEM)); Item.mask = LVIF_PARAM; Item.iItem = Index; (VOID) ListView_GetItem(GetDlgItem(hwndDlg, IDC_PROBELIST), &Item); pts = (PWSTR) Item.lParam; wcscpy(pDeviceStatusText, pts); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_HWSTATUSPAGE); } return TRUE; } } } break; case WM_DESTROY: { for (Index = ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_PROBELIST)); --Index > 0;) { ZeroMemory(&Item, sizeof(LV_ITEM)); Item.mask = LVIF_PARAM; Item.iItem = Index; (VOID) ListView_GetItem(GetDlgItem(hwndDlg, IDC_PROBELIST), &Item); HeapFree(hProcessHeap, 0, (LPVOID) Item.lParam); } HeapFree(hProcessHeap, 0, (LPVOID) pDeviceStatusText); } break; } return FALSE; } static INT_PTR CALLBACK SelectWayPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam; switch (lpnm->code) { case PSN_SETACTIVE: { PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); if (SendDlgItemMessage(hwndDlg, IDC_AUTOINSTALL, BM_GETCHECK, 0, 0) == BST_CHECKED) SendDlgItemMessage(hwndDlg, IDC_MANUALLYINST, BM_SETCHECK, 0, 0); else { SendDlgItemMessage(hwndDlg, IDC_AUTOINSTALL, BM_SETCHECK, 1, 1); SendDlgItemMessage(hwndDlg, IDC_MANUALLYINST, BM_SETCHECK, 0, 0); } } break; case PSN_WIZNEXT: { if (SendDlgItemMessage(hwndDlg, IDC_AUTOINSTALL, BM_GETCHECK, 0, 0) == BST_CHECKED) SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PROGRESSPAGE); else SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_HWTYPESPAGE); return TRUE; } } } break; } return FALSE; } static INT_PTR CALLBACK DevStatusPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { /* Set title font */ SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE); } break; case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam; switch (lpnm->code) { case PSN_SETACTIVE: { /* Set status text */ SetWindowText(GetDlgItem(hwndDlg, IDC_HWSTATUSEDIT), pDeviceStatusText); PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH | PSWIZB_BACK); } break; case PSN_WIZBACK: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PROBELISTPAGE); return TRUE; } } } break; } return FALSE; } static INT EnumDeviceClasses(INT ClassIndex, LPWSTR DevClassName, LPWSTR DevClassDesc, BOOL *DevPresent, INT *ClassImage) { GUID ClassGuid; HKEY KeyClass; WCHAR ClassName[MAX_STR_SIZE]; DWORD RequiredSize = MAX_STR_SIZE; UINT Ret; *DevPresent = FALSE; *DevClassName = L'\0'; Ret = CM_Enumerate_Classes(ClassIndex, &ClassGuid, 0); if (Ret != CR_SUCCESS) { /* All classes enumerated */ if(Ret == CR_NO_SUCH_VALUE) { hDevInfoTypes = NULL; return -1; } if (Ret == CR_INVALID_DATA) { ; /* FIXME: What should we do here? */ } /* Handle other errors... */ } if (SetupDiClassNameFromGuid(&ClassGuid, ClassName, RequiredSize, &RequiredSize)) { lstrcpy(DevClassName, ClassName); } if (!SetupDiGetClassImageIndex(&ImageListData, &ClassGuid, ClassImage)) { /* FIXME: Can we do this? * Set the blank icon: IDI_SETUPAPI_BLANK = 41 * It'll be image 24 in the imagelist */ *ClassImage = 24; } /* Get device info for all devices of a particular class */ hDevInfoTypes = SetupDiGetClassDevs(&ClassGuid, NULL, NULL, DIGCF_PRESENT); if (hDevInfoTypes == INVALID_HANDLE_VALUE) { hDevInfoTypes = NULL; return 0; } KeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid, MAXIMUM_ALLOWED, DIOCR_INSTALLER, NULL, 0); if (KeyClass != INVALID_HANDLE_VALUE) { LONG dwSize = MAX_STR_SIZE; if (RegQueryValue(KeyClass, NULL, DevClassDesc, &dwSize) != ERROR_SUCCESS) { *DevClassDesc = L'\0'; } } else { return -3; } *DevPresent = TRUE; RegCloseKey(KeyClass); return 0; } static VOID InitHardWareTypesPage(HWND hwndDlg) { HWND hList = GetDlgItem(hwndDlg, IDC_HWTYPESLIST); WCHAR DevName[MAX_STR_SIZE]; WCHAR DevDesc[MAX_STR_SIZE]; BOOL DevExist = FALSE; INT ClassRet, DevImage, Index = 0; LV_COLUMN Column; LV_ITEM Item; RECT Rect; if (!hList) return; ZeroMemory(&Column, sizeof(LV_COLUMN)); GetClientRect(hList, &Rect); Column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; Column.fmt = LVCFMT_LEFT; Column.iSubItem = 0; Column.pszText = NULL; Column.cx = Rect.right - GetSystemMetrics(SM_CXVSCROLL); (VOID) ListView_InsertColumn(hList, 0, &Column); ZeroMemory(&Item, sizeof(LV_ITEM)); do { ClassRet = EnumDeviceClasses(Index, DevName, DevDesc, &DevExist, &DevImage); if ((ClassRet != -1) && (DevExist)) { Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; Item.iItem = Index; Item.iImage = DevImage; if (DevDesc[0] != L'\0') Item.pszText = (LPWSTR) DevDesc; else Item.pszText = (LPWSTR) DevName; (VOID) ListView_InsertItem(hList, &Item); /* Kill InfoList initialized in EnumDeviceClasses */ if (hDevInfoTypes) { SetupDiDestroyDeviceInfoList(hDevInfoTypes); hDevInfoTypes = NULL; } } Index++; } while (ClassRet != -1); (VOID) ListView_SetImageList(hList, ImageListData.ImageList, LVSIL_SMALL); } static INT_PTR CALLBACK HdTypesPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { InitHardWareTypesPage(hwndDlg); } break; case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam; switch (lpnm->code) { case PSN_SETACTIVE: { PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK); } break; case PSN_WIZBACK: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SELECTWAYPAGE); return TRUE; } } } break; } return FALSE; } static INT_PTR CALLBACK ProgressPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam; switch (lpnm->code) { case PSN_SETACTIVE: { PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK); } break; case PSN_WIZBACK: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SELECTWAYPAGE); return TRUE; } } } break; } return FALSE; } static int CALLBACK PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) { // NOTE: This callback is needed to set large icon correctly. HICON hIcon; switch (uMsg) { case PSCB_INITIALIZED: { hIcon = LoadIconW(hApplet, MAKEINTRESOURCEW(IDI_CPLICON)); SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); break; } } return 0; } static VOID HardwareWizardInit(HWND hwnd) { HPROPSHEETPAGE ahpsp[10]; PROPSHEETPAGE psp = {0}; PROPSHEETHEADER psh; UINT nPages = 0; /* Create the Start page, until setup is working */ psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; psp.hInstance = hApplet; psp.lParam = 0; psp.pfnDlgProc = StartPageDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_STARTPAGE); ahpsp[nPages++] = CreatePropertySheetPage(&psp); /* Create search page */ psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SEARCHTITLE); psp.pszHeaderSubTitle = NULL; psp.hInstance = hApplet; psp.lParam = 0; psp.pfnDlgProc = SearchPageDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_SEARCHPAGE); ahpsp[nPages++] = CreatePropertySheetPage(&psp); /* Create is connected page */ psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ISCONNECTED); psp.pszHeaderSubTitle = NULL; psp.hInstance = hApplet; psp.lParam = 0; psp.pfnDlgProc = IsConnectedPageDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_ISCONNECTEDPAGE); ahpsp[nPages++] = CreatePropertySheetPage(&psp); /* Create probe list page */ psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROBELISTTITLE); psp.pszHeaderSubTitle = NULL; psp.hInstance = hApplet; psp.lParam = 0; psp.pfnDlgProc = ProbeListPageDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_PROBELISTPAGE); ahpsp[nPages++] = CreatePropertySheetPage(&psp); /* Create select search way page */ psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SELECTWAYTITLE); psp.pszHeaderSubTitle = NULL; psp.hInstance = hApplet; psp.lParam = 0; psp.pfnDlgProc = SelectWayPageDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_SELECTWAYPAGE); ahpsp[nPages++] = CreatePropertySheetPage(&psp); /* Create device status page */ psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; psp.hInstance = hApplet; psp.lParam = 0; psp.pfnDlgProc = DevStatusPageDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_HWSTATUSPAGE); ahpsp[nPages++] = CreatePropertySheetPage(&psp); /* Create hardware types page */ psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_HDTYPESTITLE); psp.pszHeaderSubTitle = NULL; psp.hInstance = hApplet; psp.lParam = 0; psp.pfnDlgProc = HdTypesPageDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_HWTYPESPAGE); ahpsp[nPages++] = CreatePropertySheetPage(&psp); /* Create progress page */ psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SEARCHTITLE); psp.pszHeaderSubTitle = NULL; psp.hInstance = hApplet; psp.lParam = 0; psp.pfnDlgProc = ProgressPageDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_PROGRESSPAGE); ahpsp[nPages++] = CreatePropertySheetPage(&psp); /* Create finish page */ psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; psp.hInstance = hApplet; psp.lParam = 0; psp.pfnDlgProc = FinishPageDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE); ahpsp[nPages++] = CreatePropertySheetPage(&psp); /* Create not connected page */ psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; psp.hInstance = hApplet; psp.lParam = 0; psp.pfnDlgProc = NotConnectedPageDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_NOTCONNECTEDPAGE); ahpsp[nPages++] = CreatePropertySheetPage(&psp); /* Create the property sheet */ psh.dwSize = sizeof(PROPSHEETHEADER); psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER | PSH_USEICONID | PSH_USECALLBACK; psh.hInstance = hApplet; psh.pszIcon = MAKEINTRESOURCEW(IDI_CPLICON); psh.hwndParent = hwnd; psh.nPages = nPages; psh.nStartPage = 0; psh.phpage = ahpsp; psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK); psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER); psh.pfnCallback = PropSheetProc; /* Create title font */ hTitleFont = CreateTitleFont(); /* Display the wizard */ PropertySheet(&psh); DeleteObject(hTitleFont); } /* FUNCTIONS ****************************************************************/ BOOL WINAPI InstallNewDevice(HWND hwndParent, LPGUID ClassGuid, PDWORD pReboot) { return FALSE; } VOID WINAPI AddHardwareWizard(HWND hwnd, LPWSTR lpName) { if (lpName != NULL) { DPRINT1("No support of remote installation yet!\n"); return; } HardwareWizardInit(hwnd); } /* Control Panel Callback */ LONG CALLBACK CPlApplet(HWND hwndCpl, UINT uMsg, LPARAM lParam1, LPARAM lParam2) { switch (uMsg) { case CPL_INIT: return TRUE; case CPL_GETCOUNT: return 1; case CPL_INQUIRE: { CPLINFO *CPlInfo = (CPLINFO*)lParam2; CPlInfo->lData = 0; CPlInfo->idIcon = IDI_CPLICON; CPlInfo->idName = IDS_CPLNAME; CPlInfo->idInfo = IDS_CPLDESCRIPTION; } break; case CPL_DBLCLK: AddHardwareWizard(hwndCpl, NULL); break; } return FALSE; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved) { UNREFERENCED_PARAMETER(lpvReserved); switch (dwReason) { case DLL_PROCESS_ATTACH: hApplet = hinstDLL; hProcessHeap = GetProcessHeap(); DisableThreadLibraryCalls(hinstDLL); break; } return TRUE; }