Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

820 lines
26 KiB

//+-------------------------------------------------------------------------
//
// 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);
}