|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation
//
// File: selclass.c
//
//--------------------------------------------------------------------------
#include "newdevp.h"
int CALLBACK ClassListCompare( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ) { TCHAR ClassDescription1[LINE_LEN]; TCHAR ClassDescription2[LINE_LEN];
UNREFERENCED_PARAMETER(lParamSort);
//
// Check if the 1st item is GUID_DEVCLASS_UNKNOWN
//
if (IsEqualGUID((LPGUID)lParam1, &GUID_DEVCLASS_UNKNOWN)) { return -1; }
//
// Check if the 2nd item is GUID_DEVCLASS_UNKNOWN
//
if (IsEqualGUID((LPGUID)lParam2, &GUID_DEVCLASS_UNKNOWN)) { return 1; }
if (SetupDiGetClassDescription((LPGUID)lParam1, ClassDescription1, LINE_LEN, NULL ) && SetupDiGetClassDescription((LPGUID)lParam2, ClassDescription2, LINE_LEN, NULL )) { return (lstrcmpi(ClassDescription1, ClassDescription2)); }
return 0; }
void InitNDW_PickClassDlg( HWND hwndClassList, PNEWDEVWIZ NewDevWiz ) { LPGUID ClassGuid, lpClassGuidSelected; GUID ClassGuidSelected; int lvIndex; DWORD ClassGuidNum; LV_ITEM lviItem; TCHAR ClassDescription[LINE_LEN];
SendMessage(hwndClassList, WM_SETREDRAW, FALSE, 0L);
//
// Clear the Class List
//
ListView_DeleteAllItems(hwndClassList);
lviItem.mask = LVIF_TEXT | LVIF_PARAM; lviItem.iItem = -1; lviItem.iSubItem = 0;
ClassGuid = NewDevWiz->ClassGuidList; ClassGuidNum = NewDevWiz->ClassGuidNum;
//
// Keep track of previosuly selected item
//
if (IsEqualGUID(&NewDevWiz->lvClassGuidSelected, &GUID_NULL)) { lpClassGuidSelected = NULL; } else { ClassGuidSelected = NewDevWiz->lvClassGuidSelected; NewDevWiz->lvClassGuidSelected = GUID_NULL; lpClassGuidSelected = &ClassGuidSelected; }
while (ClassGuidNum--) { if (SetupDiGetClassDescription(ClassGuid, ClassDescription, SIZECHARS(ClassDescription), NULL )) { if (IsEqualGUID(ClassGuid, &GUID_DEVCLASS_UNKNOWN)) {
//
// We need to special case the UNKNOWN class and to give it a
// special icon (blank) and special text (Show All Devices).
//
LoadString(hNewDev, IDS_SHOWALLDEVICES, ClassDescription, SIZECHARS(ClassDescription) ); lviItem.iImage = g_BlankIconIndex; lviItem.mask |= LVIF_IMAGE;
} else if (SetupDiGetClassImageIndex(&NewDevWiz->ClassImageList, ClassGuid, &lviItem.iImage )) {
lviItem.mask |= LVIF_IMAGE; } else { lviItem.mask &= ~LVIF_IMAGE; }
lviItem.pszText = ClassDescription; lviItem.lParam = (LPARAM) ClassGuid; lvIndex = ListView_InsertItem(hwndClassList, &lviItem);
//
// check for previous selection
//
if (lpClassGuidSelected && IsEqualGUID(lpClassGuidSelected, ClassGuid)) { ListView_SetItemState(hwndClassList, lvIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED );
lpClassGuidSelected = NULL; } }
ClassGuid++; }
//
// Sort the list
//
ListView_SortItems(hwndClassList, (PFNLVCOMPARE)ClassListCompare, NULL);
//
// if previous selection wasn't found select first in list.
//
if (IsEqualGUID(&NewDevWiz->lvClassGuidSelected, &GUID_NULL)) { lvIndex = 0; ListView_SetItemState(hwndClassList, lvIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED ); }
//
// previous selection was found, fetch its current index
//
else { lvIndex = ListView_GetNextItem(hwndClassList, -1, LVNI_SELECTED ); }
//
// scroll the selected item into view.
//
ListView_EnsureVisible(hwndClassList, lvIndex, FALSE); ListView_SetColumnWidth(hwndClassList, 0, LVSCW_AUTOSIZE_USEHEADER);
SendMessage(hwndClassList, WM_SETREDRAW, TRUE, 0L); }
INT_PTR CALLBACK NDW_PickClassDlgProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam ) { HWND hwndClassList = GetDlgItem(hDlg, IDC_NDW_PICKCLASS_CLASSLIST); HWND hwndParentDlg = GetParent(hDlg); PNEWDEVWIZ NewDevWiz = (PNEWDEVWIZ)GetWindowLongPtr(hDlg, DWLP_USER);
switch (wMsg) { case WM_INITDIALOG: { LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam; LV_COLUMN lvcCol;
NewDevWiz = (PNEWDEVWIZ)lppsp->lParam; SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NewDevWiz); SetDlgText(hDlg, IDC_NDW_TEXT, IDS_NDW_PICKCLASS1, IDS_NDW_PICKCLASS1);
//
// Get the Class Icon Image Lists. We do this only the first
// time this dialog is initialized.
//
if (NewDevWiz->ClassImageList.cbSize) { ListView_SetImageList(hwndClassList, NewDevWiz->ClassImageList.ImageList, LVSIL_SMALL ); }
//
// Insert a column for the class list
//
lvcCol.mask = LVCF_FMT | LVCF_WIDTH; lvcCol.fmt = LVCFMT_LEFT; lvcCol.iSubItem = 0; ListView_InsertColumn(hwndClassList, 0, (LV_COLUMN FAR *)&lvcCol);
//
// Save the class before the user chooses one. This will be restored
// in the event the install is cancelled.
//
NewDevWiz->SavedClassGuid = NewDevWiz->DeviceInfoData.ClassGuid;
break; }
case WM_DESTROY: break;
case WM_NOTIFY: switch (((NMHDR FAR *)lParam)->code) {
//
// This dialog is being activated. Each time we are activated
// we free up the current DeviceInfo and create a new one. Although
// inefficient, its necessary to reenumerate the class list.
//
case PSN_SETACTIVE:
PropSheet_SetWizButtons(hwndParentDlg, PSWIZB_BACK | PSWIZB_NEXT); NewDevWiz->PrevPage = IDD_NEWDEVWIZ_SELECTCLASS;
//
// If we have DeviceInfo from going forward delete it.
//
if (NewDevWiz->ClassGuidSelected) {
SetClassGuid(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, &NewDevWiz->SavedClassGuid ); }
NewDevWiz->ClassGuidSelected = NULL;
NdwBuildClassInfoList(NewDevWiz, 0); InitNDW_PickClassDlg(hwndClassList, NewDevWiz); if (NewDevWiz->InstallType == NDWTYPE_FOUNDNEW) { SetTimer(hDlg, INSTALL_COMPLETE_CHECK_TIMERID, INSTALL_COMPLETE_CHECK_TIMEOUT, NULL); } break;
case PSN_RESET: KillTimer(hDlg, INSTALL_COMPLETE_CHECK_TIMERID); SetClassGuid(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, &NewDevWiz->SavedClassGuid ); break;
case PSN_WIZBACK: NewDevWiz->PrevPage = IDD_NEWDEVWIZ_SELECTCLASS; if (NewDevWiz->EnterInto == IDD_NEWDEVWIZ_SELECTCLASS) { SetDlgMsgResult(hDlg, wMsg, NewDevWiz->EnterFrom); } KillTimer(hDlg, INSTALL_COMPLETE_CHECK_TIMERID); break;
case PSN_WIZNEXT: { LPGUID ClassGuidSelected;
SetDlgMsgResult(hDlg, wMsg, IDD_NEWDEVWIZ_SELECTDEVICE);
KillTimer(hDlg, INSTALL_COMPLETE_CHECK_TIMERID);
if (IsEqualGUID(&NewDevWiz->lvClassGuidSelected, &GUID_NULL)) { NewDevWiz->ClassGuidSelected = NULL; break; }
ClassGuidSelected = &NewDevWiz->lvClassGuidSelected; NewDevWiz->ClassGuidSelected = ClassGuidSelected;
//
// Add a new element to the DeviceInfo from the GUID and class name
//
NewDevWiz->DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiGetClassDescription(NewDevWiz->ClassGuidSelected, NewDevWiz->ClassDescription, SIZECHARS(NewDevWiz->ClassDescription), NULL ) || !SetupDiClassNameFromGuid(NewDevWiz->ClassGuidSelected, NewDevWiz->ClassName, SIZECHARS(NewDevWiz->ClassName), NULL )) { // unhandled error!
NewDevWiz->ClassGuidSelected = NULL; break; }
if (IsEqualGUID(NewDevWiz->ClassGuidSelected, &GUID_DEVCLASS_UNKNOWN)) { ClassGuidSelected = (LPGUID)&GUID_NULL; }
SetClassGuid(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, ClassGuidSelected );
break; }
case NM_DBLCLK: PropSheet_PressButton(hwndParentDlg, PSBTN_NEXT); break;
case LVN_ITEMCHANGED: { LPNM_LISTVIEW lpnmlv = (LPNM_LISTVIEW)lParam;
if ((lpnmlv->uChanged & LVIF_STATE)) { if (lpnmlv->uNewState & LVIS_SELECTED) { NewDevWiz->lvClassGuidSelected = *((LPGUID)lpnmlv->lParam); } else if (IsEqualGUID((LPGUID)lpnmlv->lParam, &NewDevWiz->lvClassGuidSelected )) { NewDevWiz->lvClassGuidSelected = GUID_NULL; } }
break; } } break;
case WM_SYSCOLORCHANGE: _OnSysColorChange(hDlg, wParam, lParam);
//
// Update the ImageList Background color
//
ImageList_SetBkColor((HIMAGELIST)SendMessage(GetDlgItem(hDlg, IDC_NDW_PICKCLASS_CLASSLIST), LVM_GETIMAGELIST, (WPARAM)(LVSIL_SMALL), 0L), GetSysColor(COLOR_WINDOW)); break;
case WM_TIMER: if (INSTALL_COMPLETE_CHECK_TIMERID == wParam) { if (IsInstallComplete(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData)) { PropSheet_PressButton(GetParent(hDlg), PSBTN_CANCEL); } } break;
default: return(FALSE); }
return(TRUE); }
//
// The real select device page is in setupapi. his page is a blank page which
// never shows its face to have a consistent place to jump to when the class
// is known.
//
INT_PTR CALLBACK NDW_SelectDeviceDlgProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam ) { HWND hwndParentDlg = GetParent(hDlg); PNEWDEVWIZ NewDevWiz = (PNEWDEVWIZ)GetWindowLongPtr(hDlg, DWLP_USER);
UNREFERENCED_PARAMETER(wParam);
switch (wMsg) { case WM_INITDIALOG: { LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam; NewDevWiz = (PNEWDEVWIZ)lppsp->lParam; SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NewDevWiz); break; }
case WM_DESTROY: break;
case WM_NOTIFY: switch (((NMHDR FAR *)lParam)->code) {
case PSN_SETACTIVE: { int PrevPage, BackUpPage;
PrevPage = NewDevWiz->PrevPage; NewDevWiz->PrevPage = IDD_NEWDEVWIZ_SELECTDEVICE; BackUpPage = NewDevWiz->EnterInto == IDD_NEWDEVWIZ_SELECTDEVICE ? NewDevWiz->EnterFrom : IDD_NEWDEVWIZ_SELECTCLASS;
if (!NewDevWiz->ClassGuidSelected || PrevPage == IDD_WIZARDEXT_SELECT) {
//
// going backwards, cleanup and backup
//
SetupDiSetSelectedDriver(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, NULL );
SetupDiDestroyDriverInfoList(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, SPDIT_COMPATDRIVER );
SetupDiDestroyDriverInfoList(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, SPDIT_CLASSDRIVER );
//
// Cleanup the WizExtSelect Page
//
if (NewDevWiz->WizExtSelect.hPropSheet) { PropSheet_RemovePage(GetParent(hDlg), (WPARAM)-1, NewDevWiz->WizExtSelect.hPropSheet ); }
SetDlgMsgResult(hDlg, wMsg, BackUpPage); break; }
//
// Set the Cursor to an Hourglass
//
SetCursor(LoadCursor(NULL, IDC_WAIT));
NewDevWiz->WizExtSelect.hPropSheet = CreateWizExtPage(IDD_WIZARDEXT_SELECT, WizExtSelectDlgProc, NewDevWiz ); if (NewDevWiz->WizExtSelect.hPropSheet) { PropSheet_AddPage(hwndParentDlg, NewDevWiz->WizExtSelect.hPropSheet); SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_SELECT); }
else { SetDlgMsgResult(hDlg, wMsg, BackUpPage); }
break; }
} break;
default: return(FALSE); }
return(TRUE); }
INT_PTR CALLBACK WizExtSelectDlgProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam ) { HWND hwndParentDlg = GetParent(hDlg); PNEWDEVWIZ NewDevWiz = (PNEWDEVWIZ )GetWindowLongPtr(hDlg, DWLP_USER); int PrevPageId; PSP_INSTALLWIZARD_DATA InstallWizard;
UNREFERENCED_PARAMETER(wParam);
switch (wMsg) { case WM_INITDIALOG: { LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam; NewDevWiz = (PNEWDEVWIZ )lppsp->lParam; SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NewDevWiz); break; }
case WM_DESTROY: break;
case WM_NOTIFY: switch (((NMHDR FAR *)lParam)->code) { case PSN_SETACTIVE:
PrevPageId = NewDevWiz->PrevPage; NewDevWiz->PrevPage = IDD_WIZARDEXT_SELECT;
if (PrevPageId == IDD_NEWDEVWIZ_SELECTDEVICE) { SP_DEVINSTALL_PARAMS DeviceInstallParams;
//
// Moving forward on first page
//
// Prepare to call the class installer, for class install wizard pages.
// and Add in setup's SelectDevice wizard page.
//
InstallWizard = &NewDevWiz->InstallDynaWiz; memset(InstallWizard, 0, sizeof(SP_INSTALLWIZARD_DATA)); InstallWizard->ClassInstallHeader.InstallFunction = DIF_INSTALLWIZARD; InstallWizard->ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); InstallWizard->hwndWizardDlg = GetParent(hDlg);
if (!SetupDiSetClassInstallParams(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, &InstallWizard->ClassInstallHeader, sizeof(SP_INSTALLWIZARD_DATA) )) { SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_SELECT); break; }
SetupDiSetSelectedDriver(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, NULL );
SetupDiDestroyDriverInfoList(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, SPDIT_COMPATDRIVER );
SetupDiDestroyDriverInfoList(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, SPDIT_CLASSDRIVER ); //
// Get current DeviceInstall parameters, and then set the fields
// we wanted changed from default
//
DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if (!SetupDiGetDeviceInstallParams(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, &DeviceInstallParams )) { SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_SELECT); break; }
DeviceInstallParams.Flags |= DI_SHOWCLASS | DI_SHOWCOMPAT | DI_SHOWOEM | DI_CLASSINSTALLPARAMS;
DeviceInstallParams.DriverPath[0] = TEXT('\0');
if (IsEqualGUID(NewDevWiz->ClassGuidSelected, &GUID_DEVCLASS_UNKNOWN)) { DeviceInstallParams.FlagsEx &= ~DI_FLAGSEX_FILTERCLASSES; } else { DeviceInstallParams.FlagsEx |= DI_FLAGSEX_FILTERCLASSES; }
//
// Check to see if we should show all class drivers or only similar
// drivers for this device.
//
if (GetBusInformation(NewDevWiz->DeviceInfoData.DevInst) & BIF_SHOWSIMILARDRIVERS) { DeviceInstallParams.FlagsEx |= DI_FLAGSEX_FILTERSIMILARDRIVERS; } else {
DeviceInstallParams.FlagsEx &= ~DI_FLAGSEX_FILTERSIMILARDRIVERS; }
DeviceInstallParams.hwndParent = hwndParentDlg; if (!SetupDiSetDeviceInstallParams(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, &DeviceInstallParams )) { SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_SELECT); break; }
InstallWizard->DynamicPageFlags = 0; NewDevWiz->SelectDevicePage = NULL;
NewDevWiz->SelectDevicePage = SetupDiGetWizardPage(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, InstallWizard, SPWPT_SELECTDEVICE, SPWP_USE_DEVINFO_DATA );
PropSheet_AddPage(hwndParentDlg, NewDevWiz->SelectDevicePage);
//
// Clear the class install parameters.
//
SetupDiSetClassInstallParams(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData, NULL, 0 );
//
// Add the end page, which is the select end page.
//
NewDevWiz->WizExtSelect.hPropSheetEnd = CreateWizExtPage(IDD_WIZARDEXT_SELECT_END, WizExtSelectEndDlgProc, NewDevWiz );
PropSheet_AddPage(hwndParentDlg, NewDevWiz->WizExtSelect.hPropSheetEnd);
PropSheet_PressButton(hwndParentDlg, PSBTN_NEXT);
}
else { //
// Moving backwards on first page
//
// Clean up proppages added.
//
if (NewDevWiz->SelectDevicePage) { PropSheet_RemovePage(hwndParentDlg, (WPARAM)-1, NewDevWiz->SelectDevicePage ); NewDevWiz->SelectDevicePage = NULL; }
if (NewDevWiz->WizExtSelect.hPropSheetEnd) { PropSheet_RemovePage(hwndParentDlg, (WPARAM)-1, NewDevWiz->WizExtSelect.hPropSheetEnd ); NewDevWiz->WizExtSelect.hPropSheetEnd = NULL; }
//
// Jump back
//
SetDlgMsgResult(hDlg, wMsg, IDD_NEWDEVWIZ_SELECTDEVICE); } break;
case PSN_WIZNEXT: SetDlgMsgResult(hDlg, wMsg, 0); break; } break;
default: return(FALSE); }
return(TRUE); }
INT_PTR CALLBACK WizExtSelectEndDlgProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam ) { HWND hwndParentDlg = GetParent(hDlg); PNEWDEVWIZ NewDevWiz = (PNEWDEVWIZ )GetWindowLongPtr(hDlg, DWLP_USER); int PrevPageId;
UNREFERENCED_PARAMETER(wParam);
switch (wMsg) { case WM_INITDIALOG: { LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam; NewDevWiz = (PNEWDEVWIZ )lppsp->lParam; SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NewDevWiz); break; }
case WM_DESTROY: break;
case WM_NOTIFY: switch (((NMHDR FAR *)lParam)->code) { case PSN_SETACTIVE:
PrevPageId = NewDevWiz->PrevPage; NewDevWiz->PrevPage = IDD_WIZARDEXT_SELECT_END;
if (PrevPageId == IDD_WIZARDEXT_SELECT) { //
// Moving forward
//
SetDlgMsgResult(hDlg, wMsg, IDD_NEWDEVWIZ_INSTALLDEV);
} else { //
// Moving backwards
//
// Clean up proppages added.
//
if (NewDevWiz->WizExtSelect.hPropSheetEnd) { PropSheet_RemovePage(hwndParentDlg, (WPARAM)-1, NewDevWiz->WizExtSelect.hPropSheetEnd ); NewDevWiz->WizExtSelect.hPropSheetEnd = NULL; }
//
// Jump back
//
NewDevWiz->PrevPage = IDD_WIZARDEXT_SELECT; SetDlgMsgResult(hDlg, wMsg, IDD_DYNAWIZ_SELECTDEV_PAGE); }
break;
case PSN_WIZNEXT: SetDlgMsgResult(hDlg, wMsg, 0); break; } break;
default: return(FALSE); }
return(TRUE); }
|