Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

4645 lines
141 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
devres.c
Abstract:
Routines for displaying resource dialogs.
Author:
Paula Tomlinson (paulat) 7-Feb-1996
Revision History:
--*/
#include "setupntp.h"
#pragma hdrstop
#define szOneDWordHexNoConflict TEXT("%08lX")
#define szOneDWordHexConflict TEXT("*%08lX")
#define szTwoDWordHexNoConflict TEXT("%08lX - %08lX")
#define szTwoDWordHexConflict TEXT("*%08lX - %08lX")
#define szOneWordHexNoConflict TEXT("%04X")
#define szOneWordHexConflict TEXT("*%04X")
#define szTwoWordHexNoConflict TEXT("%04X - %04X")
#define szTwoWordHexConflict TEXT("*%04X - %04X")
#define szOneDecNoConflict TEXT("%02d")
#define szOneDecConflict TEXT("*%02d")
PROPSHEETPAGE PropPage;
PROPSHEETHEADER PropHeader;
HPROPSHEETPAGE hPages[MAX_RES_PROPERTY_PAGES];
//
// BUGBUG (lonnym): bogus define for now!!!
//
#define IDD_HELP 1908
//
// Private Prototypes
//
LRESULT CALLBACK
ResourcePickerDlgProc(
HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam
);
void
InitDevResourceDlg(
HWND hDlg,
LPDMPROP_DATA lpdmpd,
PLOG_CONF pKnownLC,
PULONG pKnonwLCType,
PLOG_CONF pMatchingBasicLC,
HIMAGELIST himlResourceImages
);
BOOL
bIsMultiFunctionChild(
PSP_DEVINFO_DATA lpdi,
LPTSTR pszDeviceID
);
void
ShowResourceChangeControls(
HWND hDlg,
LPDMPROP_DATA lpdmpd,
int nCmdShow
);
void
LoadAllocConfig(
IN HWND hDlg,
IN LPDMPROP_DATA lpdmpd,
OUT PLOG_CONF pLogConf,
OUT PULONG pLogConfType
);
BOOL
LoadMatchingAllocConfig(
IN HWND hDlg,
IN LPDMPROP_DATA lpdmpd,
IN LOG_CONF KnownLogConf,
OUT PLOG_CONF pMatchingBasicLogConf
);
BOOL
CompareLogConf(
IN LOG_CONF KnownLogConf,
IN LOG_CONF TestLogConf
);
BOOL
DisplayKnownLogConf(
IN HWND hDlg,
IN LPDMPROP_DATA lpdmpd,
IN LOG_CONF KnownLogConf,
IN LOG_CONF MatchingLogConf
);
BOOL
GetMatchingResDes(
IN ULONG ulKnownValue,
IN ULONG ulKnownLen,
IN ULONG ulKnownEnd,
IN RESOURCEID ResType,
IN LOG_CONF MatchingLogConf,
OUT PRES_DES pMatchingResDes
);
BOOL
DisplayResourceSettings(
IN HWND hDlg,
IN LPDMPROP_DATA lpdmpd,
IN LOG_CONF LogConf,
IN ULONG ulConfigType
);
void
UpdateDevResConflictList(
IN HWND hDlg,
IN LPDMPROP_DATA lpdmpd
);
BOOL
IsInAllocValues(
IN LOG_CONF AllocLC,
IN RESOURCEID ResType,
IN ULONG ulVal,
IN ULONG ulLen
);
BOOL
DevHasKnownConfig(
IN LPDMPROP_DATA lpdmpd,
OUT PLOG_CONF pKnownLogConf,
OUT PULONG pKnowLogConfType
);
BOOL
DevHasConfig(
DEVINST DevInst,
ULONG ulConfigType
);
DWORD
GetMinLCPriority(
IN LOG_CONF LogConf
);
BOOL
bIsResourceSharable(
LOG_CONF LogConfig,
WORD wResID
);
BOOL
IsItemEditable (
int iItem,
DEVINST DevInst,
LOG_CONF RegLogConf
);
void
GetHdrValues(
IN LPBYTE pData,
IN RESOURCEID ResType,
OUT PULONG pulValue,
OUT PULONG pulLen,
OUT PULONG pulEnd,
OUT PULONG pulFlags
);
void
GetRangeValues(
IN LPBYTE pData,
IN RESOURCEID ResType,
IN ULONG ulIndex,
OUT PULONG pulValue,
OUT PULONG pulLen,
OUT PULONG pulEnd,
OUT PULONG pulFlags
);
BOOL
AlignValues(
IN OUT PULONG pulValue,
IN ULONG ulLen,
IN ULONG ulEnd,
IN ULONG ulAlignment
);
void
FormatResString(
LPTSTR lpszString,
ULONG ulVal,
ULONG ulLen,
RESOURCEID ridResType
);
BOOL
UnFormatResString(
LPTSTR lpszString,
PULONG pulVal,
PULONG pulEnd,
RESOURCEID ridResType
);
BOOL
ConvertEditText(
LPTSTR lpszConvert,
PULONG pulVal,
RESOURCEID ridResType
);
void
WarnResSettingNotEditable(
HWND hDlg,
WORD idWarning
);
LPVOID
GetListViewItemData(
HWND hList,
int iItem,
int iSubItem
);
BOOL
SaveDevResSettings(
HWND hDlg,
LPDMPROP_DATA lpdmpd,
LOG_CONF KnownLC,
ULONG KnownLCType,
LOG_CONF MatchingBasicLC,
LOG_CONF SelectedBasicLC,
BOOL bEdited
);
BOOL
SaveCustomResSettings(
IN HWND hDlg,
LPDMPROP_DATA lpdmpd,
IN LOG_CONF LogConf
);
BOOL
WriteResDesRangeToForced(
IN LOG_CONF ForcedLogConf,
IN RESOURCEID ResType,
IN ULONG RangeIndex,
IN RES_DES RD
);
BOOL
WriteValuesToForced(
IN LOG_CONF ForcedLogConf,
IN RESOURCEID ResType,
IN ULONG RangeIndex,
IN RES_DES RD,
IN ULONG ulValue,
IN ULONG ulLen,
IN ULONG ulEnd
);
BOOL
WINAPI
EditResourceDlgProc(
HWND hDlg,
UINT wMsg,
WPARAM wParam,
LPARAM lParam
);
void
InitEditResDlg(
HWND hDlg,
PRESOURCEEDITINFO lprei,
ULONG ulVal,
ULONG ulLen
);
void
UpdateMFChildList(
HWND hDlg,
PRESOURCEEDITINFO lprei
);
void
ClearEditResConflictList(
HWND hDlg,
DWORD dwFlags
);
void
UpdateEditResConflictList(
HWND hDlg,
PRESOURCEEDITINFO lprei,
ULONG ulVal,
ULONG ulLen,
ULONG ulFlags
);
ULONG
LocateValues(
IN LPBYTE pData,
IN RESOURCEID ResType,
IN ULONG ulCurrentValue,
IN ULONG ulCurrentLen,
IN ULONG ulCurrentEnd
);
void
GetOtherValues(
IN LPBYTE pData,
IN RESOURCEID ResType,
IN LONG Increment,
IN OUT PULONG pulIndex,
OUT PULONG pulValue,
OUT PULONG pulLen,
OUT PULONG pulEnd
);
BOOL
GetNextAlignedValue(
IN LPBYTE pData,
IN RESOURCEID ResType,
IN ULONG ulIndex,
IN OUT PULONG pulValue,
IN OUT PULONG pulLen,
IN OUT PULONG pulEnd
);
BOOL
GetPreviousAlignedValue(
IN LPBYTE pData,
IN RESOURCEID ResType,
IN ULONG ulIndex,
IN OUT PULONG pulValue,
IN OUT PULONG pulLen,
IN OUT PULONG pulEnd
);
BOOL
bValidateResourceVal(
HWND hDlg,
PULONG pulVal,
PULONG pulLen,
PULONG pulEnd,
PRESOURCEEDITINFO lprei
);
BOOL
bConflictWarn(
HWND hDlg,
ULONG ulVal,
ULONG ulLen,
ULONG ulEnd,
PRESOURCEEDITINFO lprei
);
BOOL
ValidateAlignment(
IN LPBYTE pData,
IN RESOURCEID ResType,
IN ULONG ulValue,
IN ULONG ulResIndex
);
BOOL
MakeResourceData(
OUT LPBYTE *ppResourceData,
OUT PULONG pulSize,
IN RESOURCEID ResType,
IN ULONG ulValue,
IN ULONG ulLen,
IN ULONG ulFlags
);
//
// Global Data
//
//
// On Windows 95, this is only set to TRUE if "minimal windows" is running.
// This is determined by seeing if GetSystemMetrics(SM_CLEANBOOT) returns
// TRUE.
//
BOOL g_bMinWin = FALSE;
static UDACCEL udAccel[] = {{0,1},{1,16},{2,256},{3,4096},{4,16000}};
HPROPSHEETPAGE
GetResourceSelectionPage(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData
)
{
LPDMPROP_DATA pdmData;
PROPSHEETPAGE PropPage;
pdmData = (LPDMPROP_DATA)MyMalloc(sizeof(DMPROP_DATA));
if (pdmData == NULL) {
return NULL;
}
pdmData->hDevInfo = DeviceInfoSet;
pdmData->lpdi = DeviceInfoData;
pdmData->szDeviceID[0] = '\0';
//
// create the Resources Property Page
//
PropPage.dwSize = sizeof(PROPSHEETPAGE);
PropPage.dwFlags = PSP_DEFAULT;
PropPage.hInstance = MyDllModuleHandle;
PropPage.pszTemplate = MAKEINTRESOURCE(IDD_DEF_DEVRESOURCE_PROP);
PropPage.pszIcon = NULL;
PropPage.pszTitle = NULL;
PropPage.pfnDlgProc = ResourcePickerDlgProc;
PropPage.lParam = (LPARAM)pdmData;
PropPage.pfnCallback = NULL;
return CreatePropertySheetPage(&PropPage);
} // GetResourceSelectionPage
DWORD
DbgSelectDeviceResources(
LPTSTR pszDeviceID
)
/*--
This is a debugging interface that allows bringing up the resource
picker for a given device instance.
--*/
{
DWORD Status = TRUE;
LPDMPROP_DATA pdmData;
SP_DEVINFO_DATA DevInfoData;
ULONG bPropStyle = TRUE;
try {
//
// Create a device info element and device info data set.
//
pdmData = (LPDMPROP_DATA)MyMalloc(sizeof(DMPROP_DATA));
if (pdmData == NULL) {
goto Clean0;
}
pdmData->hDevInfo = SetupDiCreateDeviceInfoList(NULL, NULL);
if (pdmData->hDevInfo == INVALID_HANDLE_VALUE) {
goto Clean0;
}
pdmData->szDeviceID[0] = 0x0;
pdmData->lpdi = &DevInfoData;
pdmData->lpdi->cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiOpenDeviceInfo(pdmData->hDevInfo,
pszDeviceID,
NULL,
0,
pdmData->lpdi)) {
goto Clean0;
}
if (bPropStyle) {
//
// create the Resources picker as a property page
//
PropPage.dwSize = sizeof(PROPSHEETPAGE);
PropPage.dwFlags = PSP_DEFAULT;
PropPage.hInstance = MyDllModuleHandle;
PropPage.pszTemplate = MAKEINTRESOURCE(IDD_DEF_DEVRESOURCE_PROP);
PropPage.pszIcon = NULL;
PropPage.pszTitle = NULL;
PropPage.pfnDlgProc = ResourcePickerDlgProc;
PropPage.lParam = (LPARAM)pdmData;
PropPage.pfnCallback = NULL;
hPages[0] = CreatePropertySheetPage(&PropPage);
if (hPages[0] == NULL) {
return FALSE;
}
//
// create the property sheet
//
PropHeader.dwSize = sizeof(PROPSHEETHEADER);
PropHeader.dwFlags = PSH_PROPTITLE | PSH_NOAPPLYNOW;
PropHeader.hwndParent = NULL;
PropHeader.hInstance = MyDllModuleHandle;
PropHeader.pszIcon = NULL;
PropHeader.pszCaption = TEXT("Device");
PropHeader.nPages = 1;
PropHeader.phpage = hPages;
PropHeader.nStartPage = 0;
PropHeader.pfnCallback = NULL;
PropertySheet(&PropHeader);
} else {
DialogBoxParam(MyDllModuleHandle,
MAKEINTRESOURCE(IDD_DEF_DEVRESOURCE),
NULL,
ResourcePickerDlgProc,
(LPARAM)pdmData);
}
SetupDiDestroyDeviceInfoList(pdmData->hDevInfo);
Clean0:
;
} except(EXCEPTION_EXECUTE_HANDLER) {
Status = FALSE;
}
return Status;
} // DbgSelectDeviceResources
LRESULT CALLBACK
ResourcePickerDlgProc(
HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
static LOG_CONF KnownLC, MatchingBasicLC, SelectedLC;
static ULONG KnownLCType = BASIC_LOG_CONF;
static HIMAGELIST himlResourceImages;
switch (message) {
case WM_INITDIALOG: {
LPDMPROP_DATA lpdmpd;
HICON hIcon = NULL;
int iIcon = 0, iIndex = 0;
MatchingBasicLC = SelectedLC = KnownLC = 0;
himlResourceImages = NULL;
#if 0 // for DialogBox version
lpdmpd = lParam;
#endif
lpdmpd = (LPDMPROP_DATA)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLong(hDlg, DWL_USER, (LPARAM)lpdmpd);
lpdmpd->hDlg = hDlg;
lpdmpd->dwFlags = 0;
lpdmpd->dwFlags |= DMPROP_FLAG_CHANGESSAVED; // Nothing to save yet
//
// NOTE: On Windows95, since lc info is in memory, they first
// call CM_Setup_DevNode with CM_SETUP_WRITE_LOG_CONFS flag so
// that in-memory lc data is flushed to the registry at this
// point.
//
//
// Init the Resource's image list.
//
himlResourceImages = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
ILC_MASK, // | ILC_SHARED,
1,
1);
//
// Add the resource icons to the image list
//
for (iIcon = IDI_RESOURCE_FIRST;
iIcon < IDI_RESOURCE_LAST;
++iIcon) {
hIcon = LoadIcon(MyDllModuleHandle, MAKEINTRESOURCE(iIcon));
iIndex = ImageList_AddIcon(himlResourceImages, hIcon);
}
//
// Add the overlay icons to the image list
//
for (iIcon = IDI_RESOURCEOVERLAYFIRST;
iIcon <= IDI_RESOURCEOVERLAYLAST;
++iIcon) {
hIcon = LoadIcon(MyDllModuleHandle, MAKEINTRESOURCE(iIcon));
iIndex = ImageList_AddIcon(himlResourceImages, hIcon);
//
// Tag this icon as an overlay icon (the first index is an
// index into the image list (specifies the icon), the
// second index is just an index to assign to each mask
// (starting with 1).
//
ImageList_SetOverlayImage(himlResourceImages,
iIndex,
iIcon-IDI_RESOURCEOVERLAYFIRST+1);
}
InitDevResourceDlg(hDlg,
lpdmpd,
&KnownLC,
&KnownLCType,
&MatchingBasicLC,
himlResourceImages);
break;
}
case WM_DESTROY: {
HICON hIcon;
LOG_CONF LogConf;
LONG nItems, n;
HWND hList = GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST);
PITEMDATA pItemData = NULL;
ULONG ulCount, i;
LPDMPROP_DATA lpdmpd = (LPDMPROP_DATA)GetWindowLong(hDlg, DWL_USER);
//
// Clean up the ICON resource usage
//
if ((hIcon = (HICON)LOWORD(SendDlgItemMessage(hDlg,
IDC_DEVRES_ICON, STM_GETICON, 0, 0L)))) {
DestroyIcon(hIcon);
}
//
// Free the LC handles that were saved in the combobox data
//
nItems = SendDlgItemMessage(hDlg, IDC_DEVRES_LOGCONFIGLIST,
CB_GETCOUNT, 0, 0L);
for (n = 0; n < nItems ; n++) {
LogConf = (LOG_CONF)SendDlgItemMessage(hDlg,
IDC_DEVRES_LOGCONFIGLIST,
CB_GETITEMDATA, n, 0L);
CM_Free_Log_Conf_Handle(LogConf);
}
if (KnownLC != 0) {
CM_Free_Log_Conf_Handle(KnownLC);
}
if (lpdmpd->AllocLC != 0) {
CM_Free_Log_Conf_Handle(lpdmpd->AllocLC);
}
SelectedLC = KnownLC = MatchingBasicLC = 0;
ulCount = ListView_GetItemCount(hList);
if (ulCount != LB_ERR) { // BUGBUG
for (i = 0; i < ulCount; i++) {
pItemData = (PITEMDATA)GetListViewItemData(hList, i, 0);
if (pItemData) {
free(pItemData);
}
}
}
if (himlResourceImages) {
ImageList_Destroy(himlResourceImages);
}
MyFree(lpdmpd);
break;
}
case WM_COMMAND:
switch(LOWORD(wParam)) {
case IDC_DEVRES_USESYSSETTINGS: {
LPDMPROP_DATA lpdmpd = (LPDMPROP_DATA)GetWindowLong(hDlg, DWL_USER);
if (IsDlgButtonChecked(hDlg, wParam)) {
//
// Disable Editing - Use Automatic Settings is on.
//
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_CHANGE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_LCTEXT), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_LOGCONFIGLIST), FALSE);
SelectedLC = 0;
//
// Changes were made, so they need to be saved.
//
//lpdmpd->dwFlags &= ~DMPROP_FLAG_CHANGESSAVED;
lpdmpd->dwFlags |= DMPROP_FLAG_USESYSSETTINGS;
//
// revert back to system default on display, if exists
//
if (KnownLC != 0 && MatchingBasicLC != 0) {
DisplayKnownLogConf(hDlg, lpdmpd, KnownLC,
MatchingBasicLC);
}
} else {
//
// Enable Editing - Use Automatic Settings is off.
//
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_CHANGE), TRUE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_LCTEXT), TRUE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_LOGCONFIGLIST), TRUE);
lpdmpd->dwFlags &= ~DMPROP_FLAG_USESYSSETTINGS;
}
break;
}
case IDC_DEVRES_LOGCONFIGLIST: {
if (HIWORD(wParam) == CBN_SELENDOK) {
ULONG ulIndex = 0;
WORD wItem;
HWND hwndLC = GetDlgItem(hDlg, IDC_DEVRES_LOGCONFIGLIST);
LPDMPROP_DATA lpdmpd = (LPDMPROP_DATA)GetWindowLong(hDlg, DWL_USER);
//
// If there is not a Log Config selected, then bail
//
if ((wItem = (WORD)SendMessage(hwndLC, CB_GETCURSEL, 0, 0L))
== CB_ERR) {
break;
}
if (IsWindowVisible(GetDlgItem(hDlg, IDC_DEVRES_NOALLOCTEXT))) {
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NOALLOCTEXT), SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST), SW_SHOW);
}
//
// Retrieve the Log Config handle
//
SelectedLC = (LOG_CONF)SendMessage(hwndLC, CB_GETITEMDATA,
wItem, 0L);
//
// Display the resource settings for the selected lc
//
if (DisplayResourceSettings(hDlg, lpdmpd,
SelectedLC,
BASIC_LOG_CONF)) {
lpdmpd->dwFlags |= DMPROP_FLAG_DISPLAY_BASIC;
UpdateDevResConflictList(hDlg, lpdmpd);
//
// clear the flag for saving changes
//
lpdmpd->dwFlags &= ~DMPROP_FLAG_CHANGESSAVED;
}
}
break;
}
DefDevResChangeSetting:
case IDC_DEVRES_CHANGE: {
RESOURCEEDITINFO rei;
HWND hList = GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST);
int iCur;
PITEMDATA pItemData = NULL;
TCHAR szBuffer[MAX_PATH];
LV_ITEM lviItem;
LPDMPROP_DATA lpdmpd = (LPDMPROP_DATA)GetWindowLong(hDlg, DWL_USER);
if (SelectedLC == 0 && KnownLC == 0) {
//
// No LC so warning no modifications can be made
//
WarnResSettingNotEditable(hDlg, IDS_DEVRES_NOMODIFYALL);
break;
}
//
// See if we should show the Resource list.
//
if (IsWindowVisible(GetDlgItem(hDlg, IDC_DEVRES_NOALLOCTEXT))) {
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NOALLOCTEXT), SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST), SW_SHOW);
}
//
// Check if there is a selected item, and if there is
// then throw it into the edit dialog.
//
iCur = (int)ListView_GetNextItem(hList, -1, LVNI_SELECTED);
if (iCur != LB_ERR) {
rei.KnownLC = KnownLC;
rei.MatchingBasicLC = MatchingBasicLC;
rei.SelectedBasicLC = SelectedLC;
rei.AllocLC = lpdmpd->AllocLC;
rei.lpdi = lpdmpd->lpdi;
rei.dwPropFlags = lpdmpd->dwFlags;
rei.bShareable = bIsResourceSharable(MatchingBasicLC, rei.wResNum); //BUGBUG
pItemData = (PITEMDATA)GetListViewItemData(hList, iCur, 0);
if (pItemData) {
rei.ridResType = pItemData->ResType;
rei.ResDes = pItemData->MatchingResDes;
rei.ulCurrentVal = pItemData->ulValue;
rei.ulCurrentLen = pItemData->ulLen;
rei.ulCurrentEnd = pItemData->ulEnd;
rei.ulCurrentFlags = pItemData->ulFlags;
rei.ulRangeCount = pItemData->RangeCount;
}
if (!IsItemEditable(rei.wResNum, lpdmpd->lpdi->DevInst,
MatchingBasicLC)) { //BUGBUG
//
// Warn the item is not editable
//
WarnResSettingNotEditable(hDlg, IDS_DEVRES_NOMODIFYSINGLE);
break;
}
ListView_GetItemText(hList, iCur, 1, szBuffer, MAX_PATH);
//
// Get the Current Val and Current End
//
if (UnFormatResString(szBuffer, &rei.ulCurrentVal,
&rei.ulCurrentEnd, rei.ridResType)) {
//
// Compute the Current Length
//
rei.ulCurrentLen = rei.ulCurrentEnd - rei.ulCurrentVal + 1;
if (DialogBoxParam(MyDllModuleHandle,
MAKEINTRESOURCE(IDD_EDIT_RESOURCE),
hDlg,
EditResourceDlgProc,
(LONG)(PRESOURCEEDITINFO)&rei) == IDOK) {
//
// Update The Current Resource settings to Future
// Settings, and update the Conflict list.
//
pItemData->ulValue = rei.ulCurrentVal;
pItemData->ulLen = rei.ulCurrentLen;
pItemData->ulEnd = rei.ulCurrentEnd;
pItemData->ulFlags = rei.ulCurrentFlags;
pItemData->RangeCount = rei.ulRangeCount;
FormatResString(szBuffer,
rei.ulCurrentVal,
rei.ulCurrentLen,
rei.ridResType);
ListView_SetItemText(hList, iCur, 1, szBuffer);
lviItem.mask = LVIF_PARAM;
lviItem.iSubItem = 0;
lviItem.iItem = iCur;
lviItem.lParam = (LPARAM)pItemData;
ListView_SetItem(hList, &lviItem);
//
// Update the Image for the setting based on if
// it has a conflict
//
if (rei.dwFlags & REI_FLAGS_CONFLICT) {
ListView_SetItemState(hList, iCur,
INDEXTOOVERLAYMASK(IDI_CONFLICT - IDI_RESOURCEOVERLAYFIRST + 1),
LVIS_OVERLAYMASK);
} else {
ListView_SetItemState(hList, iCur,
INDEXTOOVERLAYMASK(0),
LVIS_OVERLAYMASK);
}
ListView_RedrawItems(hList, iCur, iCur);
InvalidateRect(hList, NULL, FALSE);
UpdateWindow(hList);
UpdateDevResConflictList(hDlg, lpdmpd);
//
// clear the flag for saving changes
//
lpdmpd->dwFlags &= ~DMPROP_FLAG_CHANGESSAVED;
}
}
}
break;
}
case IDC_DEVRES_MAKEFORCED: {
LPDMPROP_DATA lpdmpd = (LPDMPROP_DATA)GetWindowLong(hDlg, DWL_USER);
//
// Show the Settings list, and Change Controls.
// Hide the message and the Make Forced button.
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST), SW_SHOW);
ShowResourceChangeControls(hDlg, NULL, SW_SHOW);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NOALLOCTEXT), SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MAKEFORCED), SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NO_RESOURCES_TEXT), SW_HIDE);
//
// Select the First basic logconfig
//
SendDlgItemMessage(hDlg, IDC_DEVRES_LOGCONFIGLIST,
CB_SETCURSEL, (WORD)0, 0L);
SelectedLC = (LOG_CONF)SendDlgItemMessage(hDlg,
IDC_DEVRES_LOGCONFIGLIST,
CB_GETITEMDATA, 0, 0L);
if (SelectedLC != 0xFFFFFFFF) {
//
// Display the first (default) settings for that log conf
//
if (DisplayResourceSettings(hDlg, lpdmpd, SelectedLC,
BASIC_LOG_CONF)) {
lpdmpd->dwFlags |= DMPROP_FLAG_DISPLAY_BASIC;
UpdateDevResConflictList(hDlg, lpdmpd);
//
// clear the flag for saving changes
//
//lpdmpd->dwFlags &= ~DMPROP_FLAG_CHANGESSAVED;
}
} else {
SelectedLC = 0;
}
break;
}
case IDC_DEVRES_MAKEFORCEDFROMALLOC: {
LPDMPROP_DATA lpdmpd = (LPDMPROP_DATA)GetWindowLong(hDlg, DWL_USER);
//
// Show the Resource Change Controls
ShowResourceChangeControls(hDlg, NULL, SW_SHOW);
//
// Hide the Give-Me-A-Forced-Config button
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MAKEFORCEDFROMALLOC), SW_HIDE);
//
// Hide the special message area
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NO_CHANGE_TEXT ), SW_HIDE);
//
// Select the First basic logconfig
//
SendDlgItemMessage(hDlg, IDC_DEVRES_LOGCONFIGLIST,
CB_SETCURSEL, (WORD)0, 0L);
SelectedLC = (LOG_CONF)SendDlgItemMessage(hDlg,
IDC_DEVRES_LOGCONFIGLIST,
CB_GETITEMDATA, 0, 0L);
if (SelectedLC != 0xFFFFFFFF) {
//
// Display the first (default) settings for that log conf
//
if (DisplayResourceSettings(hDlg, lpdmpd, SelectedLC,
BASIC_LOG_CONF)) {
lpdmpd->dwFlags |= DMPROP_FLAG_DISPLAY_BASIC;
UpdateDevResConflictList(hDlg, lpdmpd);
//
// clear the flag for saving changes
//
//lpdmpd->dwFlags &= ~DMPROP_FLAG_CHANGESSAVED;
}
} else {
SelectedLC = 0;
}
break;
}
#if 0
case IDOK: {
ULONG ulCount, i, iCur;
PITEMDATA pItemData;
HWND hList = GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST);
BOOL bRet;
LPDMPROP_DATA lpdmpd = (LPDMPROP_DATA)GetWindowLong(hDlg, DWL_USER);
//
// If there were Changes and they haven't been saved,
// then save them.
//
if (!(lpdmpd->dwFlags & DMPROP_FLAG_CHANGESSAVED)) {
bRet = SaveDevResSettings(hDlg, lpdmpd, KnownLC, KnownLCType,
MatchingBasicLC, SelectedLC,
TRUE);
} else {
bRet = SaveDevResSettings(hDlg, lpdmpd, KnownLC, KnownLCType,
MatchingBasicLC, SelectedLC,
FALSE);
}
if (bRet) {
//
// Return the flag, could be something like DI_NEEDREBOOT
// or DI_NEEDRESTART, etc.
//
ulCount = ListView_GetItemCount(hList);
for (i = 0; i < ulCount; i++) {
iCur = (int)ListView_GetNextItem(hList, i, LVNI_ALL);
pItemData = (PITEMDATA)GetListViewItemData(hList, iCur, 0);
if (pItemData) {
//free(pItemData);
}
}
EndDialog(hDlg, TRUE); //lpdmpd->lpdi->Flags);
}
return TRUE;
}
#endif
case IDCANCEL:
EndDialog(hDlg, TRUE);
break;
case IDD_HELP:
//WinHelp(hDlg, "WINDOWS.HLP>PROC4", HELP_CONTEXT, IDH_NHF_HELP);
break;
default:
break;
}
break;
case WM_NOTIFY: {
LPDMPROP_DATA lpdmpd = (LPDMPROP_DATA)GetWindowLong(hDlg, DWL_USER);
switch (((NMHDR FAR *)lParam)->code) {
case PSN_APPLY: {
ULONG ulCount, i, iCur;
PITEMDATA pItemData;
HWND hList = GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST);
BOOL bRet;
//
// If there were Changes and they haven't been saved,
// then save them.
//
if (!(lpdmpd->dwFlags & DMPROP_FLAG_CHANGESSAVED)) {
bRet = SaveDevResSettings(hDlg, lpdmpd, KnownLC, KnownLCType,
MatchingBasicLC, SelectedLC,
TRUE);
} else {
bRet = SaveDevResSettings(hDlg, lpdmpd, KnownLC, KnownLCType,
MatchingBasicLC, SelectedLC,
FALSE);
}
if (bRet) {
#if 0
if ((lpdmpd->lpdi)->Flags & DI_NEEDREBOOT) {
PropSheet_RebootSystem(GetParent(hDlg));
} else if ((lpdmpd->lpdi)->Flags & DI_NEEDRESTART) {
PropSheet_RestartWindows(GetParent(hDlg));
}
#endif
SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
} else {
SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
return TRUE;
}
break;
}
case LVN_DELETEITEM:
case LVN_DELETEALLITEMS:
//EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_CHANGE), FALSE);
break;
case LVN_ITEMCHANGED:
#if 0
//
// If the item change is comming from the resource
// list, and there is a logconfig to be edited:
//
if ((((NMHDR FAR *)lParam)->idFrom) ==
IDC_DEVRES_SETTINGSLIST) {
//
// If we should be viewing only, then break
// from here, because we don't want to turn
// on the change button.
if (lpdmpd->dwFlags &
(DMPROP_FLAG_VIEWONLYRES | DMPROP_FLAG_USESYSSETTINGS)) {
break;
}
if (MatchingBasicLC != 0 || SelectedLC != 0) {
int iCur;
//
// Check if there is a selected item.
// If yes, then activate the change button
// if the LC allows editing.
//
iCur = (int)ListView_GetNextItem(
GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST),
0xFFFF, LVNI_SELECTED);
if (iCur != LB_ERR) {
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_CHANGE), TRUE);
} else {
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_CHANGE), FALSE);
}
} else {
//
// No Matching basic log conf,
// so no editing.
//
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_CHANGE), FALSE);
}
}
#endif
break;
case NM_DBLCLK:
//
// If the double click is from the SETTINGS list
// AND the DEVRES_CHANGE button is enabled, then
// allow the change.
//
if ((((LPNMHDR)lParam)->idFrom) == IDC_DEVRES_SETTINGSLIST) {
//
// We can get double-click notifications even
// when the user doesn't click on the item's
// label.
//
if (ListView_GetNextItem(((LPNMHDR)lParam)->hwndFrom,
-1, LVNI_SELECTED) != -1) {
//
// If we are in View only mode, then do not
// allow the change.
//
if (lpdmpd->dwFlags & DMPROP_FLAG_VIEWONLYRES) {
WarnResSettingNotEditable(hDlg, IDS_DEVRES_NOMODIFYALL);
break;
}
if (IsWindowEnabled(GetDlgItem(hDlg, IDC_DEVRES_CHANGE))) {
goto DefDevResChangeSetting;
} else {
if (lpdmpd->dwFlags & DMPROP_FLAG_USESYSSETTINGS) {
//
// Cannot modify when using system
// settings.
//
WarnResSettingNotEditable(hDlg,
IDS_DEVRES_NOMODIFYSYSSET);
} else {
if (MatchingBasicLC == 0) {
WarnResSettingNotEditable(
hDlg, IDS_DEVRES_NOMODIFYALL);
} else {
WarnResSettingNotEditable(
hDlg, IDS_DEVRES_NOMODIFYSINGLE);
}
}
}
}
}
break;
}
break;
}
case WM_SYSCOLORCHANGE: {
HWND hChildWnd = GetWindow(hDlg, GW_CHILD);
while (hChildWnd != NULL) {
SendMessage(hChildWnd, WM_SYSCOLORCHANGE, wParam, lParam);
hChildWnd = GetWindow(hChildWnd, GW_HWNDNEXT);
}
break;
}
case WM_CLOSE:
SendMessage (hDlg, WM_COMMAND, IDCANCEL, 0L);
break;
case WM_HELP: // F1
//WinHelp(((LPHELPINFO)lParam)->hItemHandle, szHelpfile, HELP_WM_HELP, (DWORD)(LPSTR)aProfileIds);
break;
case WM_CONTEXTMENU: // right mouse click
//WinHelp((HWND)wParam, szHelpfile, HELP_CONTEXTMENU, (DWORD)(LPSTR)aProfileIds);
break;
}
return FALSE;
} // ResourcePickerDlgProc
void
InitDevResourceDlg(
HWND hDlg,
LPDMPROP_DATA lpdmpd,
PLOG_CONF pKnownLC,
PULONG pKnownLCType,
PLOG_CONF pMatchingBasicLC,
HIMAGELIST himlResourceImages
)
{
CONFIGRET Status = CR_SUCCESS;
HICON hIcon = NULL, hOldIcon = NULL;
LV_COLUMN LvCol;
HWND hWndList = NULL;
TCHAR szString[MAX_PATH], szTemp[MAX_PATH], szBasic[MAX_PATH],
szConfig[MAX_PATH];
ULONG ulIndex = 0, ulSize = 0;
LOG_CONF LogConf, LogConfTemp;
DWORD dwPriority = 0;
WORD wItem;
//
// Set initial control states
//
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_CHANGE), FALSE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NO_RESOURCES_TEXT), SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NOALLOCTEXT), SW_HIDE);
//
// Set the ICON and device description
//
if (SetupDiLoadClassIcon(&(lpdmpd->lpdi)->ClassGuid, &hIcon, NULL)) {
if ((hOldIcon = (HICON)LOWORD(SendDlgItemMessage(hDlg, IDC_DEVRES_ICON,
STM_SETICON,
(WPARAM)hIcon, 0L)))) {
DestroyIcon(hOldIcon);
}
}
//
// First try to get the device's friendly name, then fall back to its description,
// and finally, use the "Unknown Device" description.
//
ulSize = MAX_PATH * sizeof(TCHAR);
if (CM_Get_DevInst_Registry_Property(lpdmpd->lpdi->DevInst,
CM_DRP_FRIENDLYNAME,
NULL, (LPBYTE)szString,
&ulSize, 0) != CR_SUCCESS) {
ulSize = MAX_PATH * sizeof(TCHAR);
if (CM_Get_DevInst_Registry_Property(lpdmpd->lpdi->DevInst,
CM_DRP_DEVICEDESC,
NULL, (LPBYTE)szString,
&ulSize, 0) != CR_SUCCESS) {
LoadString(MyDllModuleHandle, IDS_DEVNAME_UNK, szString, MAX_PATH);
}
}
SetDlgItemText(hDlg, IDC_DEVRES_DEVDESC, szString);
//
// Initialize the ListView control
//
hWndList = GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST);
LvCol.mask = LVCF_TEXT;
if (LoadString(MyDllModuleHandle, IDS_RESOURCETYPE, szString, MAX_PATH)) {
LvCol.pszText = (LPTSTR)szString;
ListView_InsertColumn(hWndList, 0, (LV_COLUMN FAR *)&LvCol);
}
if (LoadString(MyDllModuleHandle, IDS_RESOURCESETTING, szString, MAX_PATH)) {
LvCol.pszText = (LPTSTR)szString;
ListView_InsertColumn(hWndList, 1, (LV_COLUMN FAR *)&LvCol);
}
ListView_SetImageList(hWndList, himlResourceImages, LVSIL_SMALL);
//
// Save a handle to the alloc config if it exists.
//
if (CM_Get_First_Log_Conf(&lpdmpd->AllocLC, lpdmpd->lpdi->DevInst,
ALLOC_LOG_CONF) != CR_SUCCESS) {
lpdmpd->AllocLC = 0;
}
//
// If this is a MultiFunction Child, disable all change controls, put up
// special text, and show the alloc config
//
if (bIsMultiFunctionChild(lpdmpd->lpdi, lpdmpd->szDeviceID)) {
DEVNODE dnParent;
ShowResourceChangeControls(hDlg, lpdmpd, SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NO_CHANGE_TEXT), SW_SHOW);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MFPARENT), SW_SHOW);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MFPARENT_DESC), SW_SHOW);
if (LoadString(MyDllModuleHandle, IDS_DEVRES_NO_CHANGE_MF, szString,
MAX_PATH)) {
SetDlgItemText(hDlg, IDC_DEVRES_NO_CHANGE_TEXT, szString);
}
//
// Get the Parent's Description.
//
LoadString(MyDllModuleHandle, IDS_DEVNAME_UNK, szString, MAX_PATH);
if (lpdmpd->lpdi->DevInst) {
if (CM_Get_Parent(&dnParent, lpdmpd->lpdi->DevInst, 0)
== CR_SUCCESS) {
ULONG ulSize = MAX_PATH * sizeof(TCHAR);
//
// First, try to retrieve friendly name, then fall back to device description.
//
if(CM_Get_DevNode_Registry_Property(dnParent, CM_DRP_FRIENDLYNAME,
NULL, szString, &ulSize, 0) != CR_SUCCESS) {
ulSize = MAX_PATH * sizeof(TCHAR);
CM_Get_DevNode_Registry_Property(dnParent, CM_DRP_DEVICEDESC,
NULL, szString, &ulSize, 0);
}
}
}
SetDlgItemText(hDlg, IDC_DEVRES_MFPARENT_DESC, szString);
LoadAllocConfig(hDlg, lpdmpd, pKnownLC, pKnownLCType);
return;
}
//
// Enable Resource Changes by default
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NO_CHANGE_TEXT), SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MFPARENT), SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MFPARENT_DESC), SW_HIDE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_CHANGE), TRUE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_LCTEXT), TRUE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_LOGCONFIGLIST), TRUE);
//
// Disable "use automatic settings" by default for now since we
// can't really pick any intelligent resources yet.
//
CheckDlgButton(hDlg, IDC_DEVRES_USESYSSETTINGS, 0);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_USESYSSETTINGS), FALSE);
lpdmpd->dwFlags &= ~DMPROP_FLAG_USESYSSETTINGS;
//
// Retrieve any FILTERED log configs for this device and add to
// log config combobox. (use BASIC for now) BUGBUG
//
LoadString(MyDllModuleHandle, IDS_BASICCONFIG, szBasic, MAX_PATH);
Status = CM_Get_First_Log_Conf(&LogConf,
lpdmpd->lpdi->DevInst,
BASIC_LOG_CONF);
if (Status == CR_SUCCESS) {
while (Status == CR_SUCCESS) {
//
// Add this FILTERED log conf to the Combobox
//
wsprintf(szTemp, TEXT("%s %04u"), szBasic, ulIndex);
wItem = (WORD)SendDlgItemMessage(hDlg, IDC_DEVRES_LOGCONFIGLIST,
CB_ADDSTRING, 0,
(LPARAM)(LPSTR)szTemp);
//
// Save the log config handle as the item data in the combobox
//
SendDlgItemMessage(hDlg, IDC_DEVRES_LOGCONFIGLIST, CB_SETITEMDATA,
wItem, (LPARAM)LogConf);
//
// Get the next FILTERED log conf
//
Status = CM_Get_Next_Log_Conf(&LogConf, LogConf, 0);
ulIndex++;
}
#if 0
} else {
//
// There are no FILTERNED LC's so don't allow resource changes.
//
lpdmpd->dwFlags |= DMPROP_FLAG_VIEWONLYRES;
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_CHANGE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_LCTEXT), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_LOGCONFIGLIST), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_USESYSSETTINGS),FALSE);
LoadAllocConfig(hDlg, lpdmpd, pKnownLC, pKnownLCType);
#endif
}
if (!SendDlgItemMessage(hDlg, IDC_DEVRES_LOGCONFIGLIST, CB_GETCOUNT, 0, 0L)) {
//
// There are no FILTERNED LC's so don't allow resource changes.
//
lpdmpd->dwFlags |= DMPROP_FLAG_VIEWONLYRES;
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_CHANGE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_LCTEXT), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_LOGCONFIGLIST), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_USESYSSETTINGS),FALSE);
LoadAllocConfig(hDlg, lpdmpd, pKnownLC, pKnownLCType); // BUGBUG, why??
} else {
//
// there's at least one entry in the combobox, select first item
// for now
//
SendDlgItemMessage(hDlg, IDC_DEVRES_LOGCONFIGLIST, CB_SETCURSEL, 0, 0L);
}
//
// Figure out which LC the current alloc config is based on.
// If none, then assume there is a problem with the LC's, and do
// not allow editing.
//
if (!(lpdmpd->dwFlags & DMPROP_FLAG_VIEWONLYRES)) {
if (!DevHasKnownConfig(lpdmpd, pKnownLC, pKnownLCType)) {
//
// The device does not have an allocated config. In this
// case we warn the user that they should probably enable
// the device.
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST), SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NOALLOCTEXT), SW_SHOW);
LoadString(MyDllModuleHandle, IDS_DEVRES_NOALLOC1, szTemp, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_DEVRES_NOALLOC2, szString, MAX_PATH);
lstrcat(szTemp, TEXT(" "));
lstrcat(szTemp, szString);
SetDlgItemText(hDlg, IDC_DEVRES_NOALLOCTEXT, szTemp);
//
// Hide the Change Controls
//
ShowResourceChangeControls(hDlg, NULL, SW_HIDE);
//
// Show the Give-Me-A-Forced-Config button
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MAKEFORCED), SW_SHOW);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MAKEFORCEDFROMALLOC), SW_HIDE);
} else {
if (LoadMatchingAllocConfig(hDlg, lpdmpd, *pKnownLC,
pMatchingBasicLC)) {
//
// This is the only case where resource changes are allowed -
// there is a known config that matches a basic/filtered
// config.
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NOALLOCTEXT), SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MAKEFORCED), SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MAKEFORCEDFROMALLOC), SW_HIDE);
} else {
//
// The resource the device is currently using do not match
// any of our logconfigs. In this case we show the allocated
// config, and warn that there is a possible problem.
//
ShowResourceChangeControls(hDlg, NULL, SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MAKEFORCED), SW_HIDE);
//
// Show the Give-Me-A-Forced-Config button
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MAKEFORCEDFROMALLOC), SW_SHOW);
//
// Add some text to the special message area
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NO_CHANGE_TEXT), SW_SHOW);
LoadString(MyDllModuleHandle, IDS_DEVRES_NOMATCHINGLC1, szTemp, MAX_PATH);
SetDlgItemText(hDlg, IDC_DEVRES_NO_CHANGE_TEXT, szTemp);
//
// Show the allocated Config
//
LoadAllocConfig(hDlg, lpdmpd, pKnownLC, pKnownLCType);
}
}
// BUGBUG, find min priority of all lc's associated with this devinst
dwPriority = LCPRI_NORMAL; //GetMinLCPriority(LC);
//
// If there is a LC with a Priority between HARDWIRED and
// LASTSOFTCONFIG, OR there is a BOOT config then allow system
// choosen settings. In the boot config case we are only
// interested in legacy devices with a detected boot config.
//
#if 0
if (((dwPriority >= LCPRI_DESIRED) && (dwPriority <= LCPRI_LASTSOFTCONFIG)) ||
DevHasConfig(lpdmpd->lpdi->DevInst, BOOT_LOG_CONF)) {
//
// Enable the Check box
//
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_USESYSSETTINGS), TRUE);
//
// If the DevInst does not have a BOOT or a FORCED config, then
// clear the check box, otherwise check it.
//
if (DevHasConfig(lpdmpd->lpdi->DevInst, FORCED_LOG_CONF)) {
CheckDlgButton(hDlg, IDC_DEVRES_USESYSSETTINGS, 0);
lpdmpd->dwFlags &= ~DMPROP_FLAG_USESYSSETTINGS;
} else {
CheckDlgButton(hDlg, IDC_DEVRES_USESYSSETTINGS, 1);
lpdmpd->dwFlags |= DMPROP_FLAG_USESYSSETTINGS;
//
// disable resource changes
//
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_CHANGE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_LCTEXT), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_LOGCONFIGLIST), FALSE);
}
} else {
EnableWindow(GetDlgItem(hDlg, IDC_DEVRES_USESYSSETTINGS), FALSE);
lpdmpd->dwFlags &= ~DMPROP_FLAG_USESYSSETTINGS;
}
#endif
//
// If we have a selected LogConfig, update the conflict list.
// This can only happen if we are NOT in view only mode
//
if (*pKnownLC != 0) {
UpdateDevResConflictList(hDlg, lpdmpd);
}
}
return;
} // InitDevResourceDlg
BOOL
bIsMultiFunctionChild(
PSP_DEVINFO_DATA lpdi,
LPTSTR pszDeviceID
)
{
ULONG Status, ProblemNumber;
if (lpdi->DevInst) {
if (CM_Get_DevNode_Status(&Status, &ProblemNumber,
lpdi->DevInst, 0) == CR_SUCCESS) {
//
// If the passed in dev is not an MF child, then it is the top
// level MF_Parent
//
if (Status & DN_MF_CHILD) {
return TRUE;
} else {
return FALSE;
}
}
}
//
// No Devnode (must be in clean boot), look at our registry path to
// see if we are a MF device
//
#if 0
if (wcsstr(pszDeviceID, REGSTR_PATH_MULTI_FUNCTION TEXT("\\"))) {
return TRUE;
} else {
return FALSE;
}
#endif
return FALSE;
} // bIsMultiFunctionChild
void
ShowResourceChangeControls(
HWND hDlg,
LPDMPROP_DATA lpdmpd,
int nCmdShow
)
{
if (lpdmpd) {
if (nCmdShow == SW_HIDE) {
lpdmpd->dwFlags |= DMPROP_FLAG_VIEWONLYRES;
} else {
lpdmpd->dwFlags &= ~DMPROP_FLAG_VIEWONLYRES;
}
}
//
// Enable the Log Config control depending on if there are any log
// config.
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_CHANGE), nCmdShow);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_LCTEXT), nCmdShow);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_LOGCONFIGLIST), nCmdShow);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_USESYSSETTINGS), nCmdShow);
return;
} // ShowResourceChangeControls
void
LoadAllocConfig(
IN HWND hDlg,
IN LPDMPROP_DATA lpdmpd,
OUT PLOG_CONF pLogConf,
OUT PULONG pLogConfType
)
{
CONFIGRET Status = CR_SUCCESS;
HWND hWndList = NULL;
RES_DES ResDes;
RESOURCEID ResType;
//
// Clear the Resource List
//
hWndList = GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST);
ListView_DeleteAllItems(hWndList);
//
// Display the Current Allocated Config.
//
if (CM_Get_First_Log_Conf(pLogConf,
lpdmpd->lpdi->DevInst,
ALLOC_LOG_CONF) == CR_SUCCESS) {
lpdmpd->dwFlags |= DMPROP_FLAG_DISPLAY_ALLOC;
*pLogConfType = ALLOC_LOG_CONF;
DisplayKnownLogConf(hDlg, lpdmpd, *pLogConf, 0);
} else {
//
// No ALLOC Config
//
TCHAR szMessage[512];
//
// Hide the Resource List controls, and Show the Text.
//
ShowWindow(hWndList, SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_SETTINGSTATE), SW_HIDE);
ShowResourceChangeControls(hDlg, NULL, SW_HIDE);
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NO_RESOURCES_TEXT), SW_SHOW);
//
// Hide the Give-Me-A-Forced-Config From Alloc button
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MAKEFORCEDFROMALLOC), SW_HIDE);
//
// Hide the special message area
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_NO_CHANGE_TEXT), SW_HIDE);
//
// Show the Make a forced config button.
//
ShowWindow(GetDlgItem(hDlg, IDC_DEVRES_MAKEFORCED), SW_SHOW);
LoadString(MyDllModuleHandle, IDS_DEVRES_NO_RESOURCES1, szMessage, 512);
if (g_bMinWin) {
LoadString(MyDllModuleHandle, IDS_DEVRES_NO_RESOURCES2,
szMessage+lstrlen(szMessage), 512-lstrlen(szMessage));
} else {
LoadString(MyDllModuleHandle, IDS_DEVRES_NO_RESOURCES3,
szMessage+lstrlen(szMessage), 512-lstrlen(szMessage));
}
SetDlgItemText(hDlg, IDC_DEVRES_NO_RESOURCES_TEXT, szMessage);
}
return;
} // LoadAllocConfig
BOOL
LoadMatchingAllocConfig(
IN HWND hDlg,
IN LPDMPROP_DATA lpdmpd,
IN LOG_CONF KnownLogConf,
OUT PLOG_CONF pMatchingBasicLogConf
)
{
ULONG ulBasicLC = 0;
BOOL bFoundCorrectLC = FALSE;
LOG_CONF LogConf;
//
// Load the values associated with the allocated config in the list box,
// but associate each with the resource requirements descriptor that it
// originated from. To do this, we have to match the allocated config
// with the basic/filtered config it is based on.
//
// NOTE: if we got here, then we know that an known config of some kind
// exists (passed in as param) and that at least one basic/filtered config
// exists. Further more, we know that the combobox has already been
// filled in with a list of any basic/filtered configs and the lc handle
// associated with them.
//
while (SendDlgItemMessage(hDlg, IDC_DEVRES_LOGCONFIGLIST, CB_SETCURSEL,
ulBasicLC, 0L) != LB_ERR) {
//
// Retrieve the log conf handle
//
LogConf = (LOG_CONF)SendDlgItemMessage(hDlg, IDC_DEVRES_LOGCONFIGLIST,
CB_GETITEMDATA, ulBasicLC, 0L);
if (CompareLogConf(KnownLogConf, LogConf)) {
DisplayKnownLogConf(hDlg, lpdmpd, KnownLogConf, LogConf);
*pMatchingBasicLogConf = LogConf;
bFoundCorrectLC = TRUE;
break;
}
ulBasicLC++;
}
return bFoundCorrectLC;
} // LoadMatchingAllocConfig
BOOL
CompareLogConf(
IN LOG_CONF KnownLogConf,
IN LOG_CONF TestLogConf
)
{
CONFIGRET Status = CR_SUCCESS;
BOOL bMatch = TRUE;
RES_DES ResDes, ResDesTemp, MatchingResDes;
RESOURCEID ResType;
ULONG i, ulSize, ulValue, ulLen, ulEnd, ulFlags;
LPBYTE pData = NULL;
ULONG KnownResCount[ResType_MAX+1],
TestResCount[ResType_MAX+1];
//
// The KnownLogConf is a resource list and the TestLogConf is a requirements
// list that might be a match
//
for (i = 1; i <= ResType_MAX; i++) {
KnownResCount[i] = 0;
TestResCount[i] = 0;
}
Status = CM_Get_Next_Res_Des(&ResDes, KnownLogConf, ResType_All, &ResType, 0);
while (Status == CR_SUCCESS) {
//
// Get res des data for KnownLogConf (resource list)
//
if (CM_Get_Res_Des_Data_Size(&ulSize, ResDes, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(ResDes);
break;
}
pData = malloc(ulSize);
if (pData == NULL) {
CM_Free_Res_Des_Handle(ResDes);
break;
}
if (CM_Get_Res_Des_Data(ResDes, pData, ulSize, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(ResDes);
free(pData);
break;
}
GetHdrValues(pData, ResType, &ulValue, &ulLen, &ulEnd, &ulFlags);
//
// see if there's a res des in the test TestLogConf (requirements list)
// that matches this res des
//
if (!GetMatchingResDes(ulValue, ulLen, ulEnd, ResType,
TestLogConf, &MatchingResDes)) {
//
// Found a res des that has no match in the requirements
// list so the log confs aren't a match.
//
free(pData);
CM_Free_Res_Des_Handle(MatchingResDes);
bMatch = FALSE;
break;
}
//
// Keep track of how many of each type of resource occured in
// the known lc - this is a secondary check to make sure we've
// got a real match and not a superset.
//
KnownResCount[ResType]++;
//
// Get next res des in KnownLogConf (resource list)
//
ResDesTemp = ResDes;
Status = CM_Get_Next_Res_Des(&ResDes, ResDesTemp,
ResType_All, &ResType, 0);
CM_Free_Res_Des_Handle(ResDesTemp);
free(pData);
}
if (bMatch) {
//
// If there's a match, then we still have to do one more check.
// Make sure that the known log conf is not a superset of the
// test log conf by checking the total number of resource
// descriptors in each log conf.
//
Status = CM_Get_Next_Res_Des(&ResDes, TestLogConf, ResType_All, &ResType, 0);
while (Status == CR_SUCCESS) {
TestResCount[ResType]++;
ResDesTemp = ResDes;
Status = CM_Get_Next_Res_Des(&ResDes, ResDesTemp, ResType_All, &ResType, 0);
CM_Free_Res_Des_Handle(ResDesTemp);
}
for (i = 1; i <= ResType_MAX; i++) {
if (KnownResCount[i] != TestResCount[i]) {
bMatch = FALSE;
}
}
}
return bMatch;
} // CompareLogConf
BOOL
DisplayKnownLogConf(
IN HWND hDlg,
IN LPDMPROP_DATA lpdmpd,
IN LOG_CONF KnownLogConf,
IN LOG_CONF MatchingLogConf
)
{
//
// Displays resource settings from a resource list
//
CONFIGRET Status = CR_SUCCESS;
HWND hWndList;
LV_ITEM lviItem, lviSubItem;
TCHAR szTemp[MAX_PATH];
int iNewItem = 0;
ULONG ulValue, ulLen, ulEnd, ulSize, ulFlags;
LPBYTE pData = NULL;
RES_DES ResDes, ResDesTemp, MatchingResDes;
RESOURCEID ResType;
PITEMDATA pItemData = NULL;
hWndList = GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST);
SendMessage(hWndList, WM_SETREDRAW, (WPARAM)FALSE, 0);
ListView_DeleteAllItems(hWndList);
//
// setup values that will remain the same each time I add an item
//
lviItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
lviItem.pszText = szTemp; // reuse the szTemp buffer
lviItem.iSubItem = 0;
lviItem.iImage = IDI_RESOURCE - IDI_RESOURCE_FIRST;
//
// setup values that will remain the same each time I add a subitem
//
lviSubItem.mask = LVIF_TEXT | LVIF_PARAM;
lviSubItem.iSubItem = 1;
lviSubItem.pszText = szTemp; // reuse the szTemp buffer
SendMessage(hWndList, WM_SETREDRAW, (WPARAM)FALSE, 0);
//
// Get first res des in known log conf
//
Status = CM_Get_Next_Res_Des(&ResDes, KnownLogConf, ResType_All, &ResType, 0);
while (Status == CR_SUCCESS) {
if (ResType > ResType_None && ResType <= ResType_MAX) {
//
// Get res des data
//
if (CM_Get_Res_Des_Data_Size(&ulSize, ResDes, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(ResDes);
break;
}
pData = malloc(ulSize);
if (pData == NULL) {
CM_Free_Res_Des_Handle(ResDes);
break;
}
if (CM_Get_Res_Des_Data(ResDes, pData, ulSize, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(ResDes);
free(pData);
break;
}
GetHdrValues(pData, ResType, &ulValue, &ulLen, &ulEnd, &ulFlags);
//
// Find matching res des in matching log conf
//
MatchingResDes = 0;
if (MatchingLogConf != 0) {
GetMatchingResDes(ulValue, ulLen, ulEnd, ResType,
MatchingLogConf, &MatchingResDes);
}
//
// Write first column text field (uses szTemp)
//
LoadString(MyDllModuleHandle, IDS_RESTYPE_FULL + ResType,
szTemp, MAX_PATH);
pItemData = (PITEMDATA)malloc(sizeof(ITEMDATA));
if (pItemData != NULL) {
pItemData->ResType = ResType;
pItemData->MatchingResDes = MatchingResDes;
pItemData->RangeCount = 0;
pItemData->ulValue = ulValue;
pItemData->ulLen = ulLen;
pItemData->ulEnd = ulValue + ulLen - 1;
pItemData->ulFlags = ulFlags;
}
lviItem.iItem = iNewItem;
lviItem.lParam = (LPARAM)pItemData;
ListView_InsertItem(hWndList, &lviItem);
//
// Write second column text field (uses szTemp)
//
FormatResString(szTemp, ulValue, ulLen, ResType);
ListView_SetItemText(hWndList, iNewItem, 1, szTemp);
//
// Get next res des in log conf
//
ResDesTemp = ResDes;
Status = CM_Get_Next_Res_Des(&ResDes, ResDesTemp,
ResType_All, &ResType, 0);
CM_Free_Res_Des_Handle(ResDesTemp);
free(pData);
++iNewItem;
}
}
SendMessage(hWndList, WM_SETREDRAW, (WPARAM)TRUE, 0);
if (Status != CR_SUCCESS && Status != CR_NO_MORE_RES_DES) {
return FALSE;
}
ListView_SetColumnWidth(hWndList, 0, LVSCW_AUTOSIZE_USEHEADER);
ListView_SetColumnWidth(hWndList, 1, LVSCW_AUTOSIZE_USEHEADER);
ListView_SetItemState(hWndList, 0, (LVIS_SELECTED| LVIS_FOCUSED),
(LVIS_SELECTED | LVIS_FOCUSED));
//
// Update the Conflict list
//
UpdateDevResConflictList(hDlg, lpdmpd);
return TRUE;
} // DisplayKnownLogConf
BOOL
GetMatchingResDes(
IN ULONG ulKnownValue,
IN ULONG ulKnownLen,
IN ULONG ulKnownEnd,
IN RESOURCEID ResType,
IN LOG_CONF MatchingLogConf,
OUT PRES_DES pMatchingResDes
)
{
CONFIGRET Status = CR_SUCCESS;
RESOURCEID Res;
RES_DES ResDes, ResDesTemp;
ULONG ulSize, ulValue = 0, ulLen = 0, ulEnd = 0, ulFlags = 0, i;
PGENERIC_RESOURCE pGenRes;
BOOL bMatch = FALSE;
LPBYTE pData = NULL;
//
// The MatchingLogConf is a requirements list. Loop through each res des
// in the matching log conf until we find a res des that matches the
// known res des values.
//
Status = CM_Get_Next_Res_Des(&ResDes, MatchingLogConf, ResType, &Res, 0);
while (Status == CR_SUCCESS) {
//
// Get res des data
//
if (CM_Get_Res_Des_Data_Size(&ulSize, ResDes, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(ResDes);
break;
}
pData = malloc(ulSize);
if (pData == NULL) {
CM_Free_Res_Des_Handle(ResDes);
break;
}
if (CM_Get_Res_Des_Data(ResDes, pData, ulSize, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(ResDes);
free(pData);
break;
}
pGenRes = (PGENERIC_RESOURCE)pData;
for (i = 0; i < pGenRes->GENERIC_Header.GENERIC_Count; i++) {
GetRangeValues(pData, ResType, i, &ulValue, &ulLen, &ulEnd, &ulFlags);
if ((ulKnownLen == ulLen) &&
(ulKnownValue >= ulValue) &&
(ulKnownEnd <= ulEnd)) {
*pMatchingResDes = ResDes;
bMatch = TRUE;
free(pData);
goto MatchFound;
}
}
//
// Get next res des in log conf
//
ResDesTemp = ResDes;
Status = CM_Get_Next_Res_Des(&ResDes, ResDesTemp,
ResType, &Res, 0);
CM_Free_Res_Des_Handle(ResDesTemp);
free(pData);
}
MatchFound:
return bMatch;
} // GetMatchingResDes
BOOL
DisplayResourceSettings(
IN HWND hDlg,
IN LPDMPROP_DATA lpdmpd,
IN LOG_CONF LogConf,
IN ULONG ulConfigType
)
{
//
// Displays resource settings from a requirements list
//
CONFIGRET Status = CR_SUCCESS;
HWND hWndList;
LV_ITEM lviItem, lviSubItem;
TCHAR szTemp[MAX_PATH];
int iNewItem = 0;
ULONG ulValue, ulLen, ulEnd, ulSize, ulFlags;
LPBYTE pData = NULL;
RES_DES ResDes, ResDesTemp;
RESOURCEID ResType;
PITEMDATA pItemData = NULL;
hWndList = GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST);
SendMessage(hWndList, WM_SETREDRAW, (WPARAM)FALSE, 0);
ListView_DeleteAllItems(hWndList);
//
// setup values that will remain the same each time I add an item
//
lviItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
lviItem.pszText = szTemp; // reuse the szTemp buffer
lviItem.iSubItem = 0;
lviItem.iImage = IDI_RESOURCE - IDI_RESOURCE_FIRST;
//
// setup values that will remain the same each time I add a subitem
//
lviSubItem.mask = LVIF_TEXT | LVIF_PARAM;
lviSubItem.iSubItem = 1;
lviSubItem.pszText = szTemp; // reuse the szTemp buffer
SendMessage(hWndList, WM_SETREDRAW, (WPARAM)FALSE, 0);
//
// Get first res des in specified log conf
//
Status = CM_Get_Next_Res_Des(&ResDes, LogConf, ResType_All, &ResType, 0);
while (Status == CR_SUCCESS) {
if (ResType > ResType_None && ResType <= ResType_MAX) {
//
// Get res des data
//
if (CM_Get_Res_Des_Data_Size(&ulSize, ResDes, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(ResDes);
break;
}
pData = malloc(ulSize);
if (pData == NULL) {
CM_Free_Res_Des_Handle(ResDes);
break;
}
if (CM_Get_Res_Des_Data(ResDes, pData, ulSize, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(ResDes);
free(pData);
break;
}
if (ulConfigType == BASIC_LOG_CONF ||
ulConfigType == FILTERED_LOG_CONF) {
GetRangeValues(pData, ResType, 0, &ulValue, &ulLen, &ulEnd, &ulFlags);
} else {
GetHdrValues(pData, ResType, &ulValue, &ulLen, &ulEnd, &ulFlags);
}
//
// Write first column text field (uses szTemp, lParam is res type)
//
LoadString(MyDllModuleHandle, IDS_RESTYPE_FULL + ResType,
szTemp, MAX_PATH);
pItemData = (PITEMDATA)malloc(sizeof(ITEMDATA));
if (pItemData != NULL) {
pItemData->ResType = ResType;
pItemData->MatchingResDes = ResDes;
pItemData->RangeCount = 0;
pItemData->ulValue = ulValue;
pItemData->ulLen = ulLen;
pItemData->ulEnd = ulValue + ulLen - 1;
pItemData->ulFlags = ulFlags;
}
lviItem.iItem = iNewItem;
lviItem.lParam = (LPARAM)pItemData;
ListView_InsertItem(hWndList, &lviItem);
//
// Write second column text field (uses szTemp, lParam is res handle)
//
FormatResString(szTemp, ulValue, ulLen, ResType);
ListView_SetItemText(hWndList, iNewItem, 1, szTemp);
//
// Get next res des in log conf
//
Status = CM_Get_Next_Res_Des(&ResDes, ResDes,
ResType_All, &ResType, 0);
free(pData);
++iNewItem;
}
}
SendMessage(hWndList, WM_SETREDRAW, (WPARAM)TRUE, 0);
if (Status != CR_SUCCESS && Status != CR_NO_MORE_RES_DES) {
return FALSE;
}
ListView_SetColumnWidth(hWndList, 0, LVSCW_AUTOSIZE_USEHEADER);
ListView_SetColumnWidth(hWndList, 1, LVSCW_AUTOSIZE_USEHEADER);
ListView_SetItemState(hWndList, 0, (LVIS_SELECTED| LVIS_FOCUSED),
(LVIS_SELECTED | LVIS_FOCUSED));
//
// Update the Conflict list
//
UpdateDevResConflictList(hDlg, lpdmpd);
return TRUE;
} // DisplayResourceSettings
void
UpdateDevResConflictList(
IN HWND hDlg,
IN LPDMPROP_DATA lpdmpd
)
{
CONFIGRET Status = CR_SUCCESS;
TCHAR szTemp[MAX_PATH], szBuffer[MAX_PATH], szSetting[MAX_PATH],
szFormat[MAX_PATH];
LPTSTR pszConflictList = NULL, pszConflict = NULL;
ULONG ulCount = 0, i = 0, ulSize = 0, ulLength, ulBufferLen;
PITEMDATA pItemData = NULL;
LPBYTE pResourceData = NULL;
BOOL bConflict = FALSE;
HWND hwndResList = GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST);
#if 0
rcwData.bShareable = bIsResourceSharable(lpbLogConfig, LOWORD(dwIData));
#endif
ulCount = ListView_GetItemCount(hwndResList);
if (ulCount == LB_ERR) {
goto Clean0;
}
#if 0
if (lpdmpd->dwFlags & DMPROP_FLAG_DISPLAY_ALLOC) {
//
// Don't report conflicts if it's an ALLOC config that's being
// displayed because we will be reporting conflicts against
// against the target device.
//
goto Clean0;
}
#endif
ulBufferLen = 2048;
ulLength = 0;
pszConflictList = MyMalloc(ulBufferLen * sizeof(TCHAR));
if (pszConflictList == NULL) {
goto Clean0;
}
pszConflict = pszConflictList;
*pszConflictList = 0x0;
for (i = 0; i < ulCount; i++) {
pItemData = (PITEMDATA)GetListViewItemData(hwndResList, i, 0);
//
// There's also still a chance that these values match what's
// in the ALLOC config for this device, if so then skip this
// resource since we'd only be detecting a conflict with
// ourselves.
//
if (lpdmpd->AllocLC != 0) {
if (IsInAllocValues(lpdmpd->AllocLC,
pItemData->ResType,
pItemData->ulValue,
pItemData->ulLen)) {
goto NextResource;
}
}
if (MakeResourceData(&pResourceData, &ulSize,
pItemData->ResType,
pItemData->ulValue,
pItemData->ulLen,
pItemData->ulFlags)) {
Status = CM_Detect_Resource_Conflict(lpdmpd->lpdi->DevInst,
pItemData->ResType,
pResourceData,
ulSize,
&bConflict,
0);
if (Status == CR_SUCCESS && bConflict) {
//
// There's a known conflict with this resource, we display
// an overlay icon to indicate the conflict and display
// text of the form:
// <resource type> xx conflicts with another device.
//
ListView_GetItemText(hwndResList, i, 1, szSetting, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_CONFLICT_FMT, szFormat, MAX_PATH);
switch (pItemData->ResType) {
case ResType_Mem:
LoadString(MyDllModuleHandle, IDS_MEMORY_FULL, szBuffer, MAX_PATH);
break;
case ResType_IO:
LoadString(MyDllModuleHandle, IDS_IO_FULL, szBuffer, MAX_PATH);
break;
case ResType_DMA:
LoadString(MyDllModuleHandle, IDS_DMA_FULL, szBuffer, MAX_PATH);
break;
case ResType_IRQ:
LoadString(MyDllModuleHandle, IDS_IRQ_FULL, szBuffer, MAX_PATH);
break;
}
wsprintf(szTemp, // holds complete description
szFormat, // string format layout
szBuffer, // describes resource type
szSetting); // resource setting values
ulLength += lstrlen(szTemp) + 1;
if (ulLength < ulBufferLen) {
lstrcpy(pszConflict, szTemp);
pszConflict += lstrlen(pszConflict);
}
//
// Set the Conflict Overlay for this resource.
//
ListView_SetItemState(hwndResList, i,
INDEXTOOVERLAYMASK(IDI_CONFLICT - IDI_RESOURCEOVERLAYFIRST + 1),
LVIS_OVERLAYMASK);
} else {
ListView_SetItemState(hwndResList, i,
INDEXTOOVERLAYMASK(0),
LVIS_OVERLAYMASK);
}
if (Status == CR_SUCCESS && pResourceData != NULL) {
free(pResourceData);
}
}
NextResource:
;
}
Clean0:
;
//
// If there were any conflicts, put the list in the multiline edit box.
//
if (pszConflictList == NULL || *pszConflictList == 0x0) {
LoadString(MyDllModuleHandle, IDS_DEVRES_NOCONFLICTDEVS, szBuffer, MAX_PATH);
SetDlgItemText(hDlg, IDC_DEVRES_CONFLICTINFOLIST, szBuffer);
} else {
SetDlgItemText(hDlg, IDC_DEVRES_CONFLICTINFOLIST, pszConflictList);
MyFree(pszConflictList);
}
return;
} // UpdateDevResConflictList
BOOL
IsInAllocValues(
IN LOG_CONF AllocLC,
IN RESOURCEID ResType,
IN ULONG ulVal,
IN ULONG ulLen
)
{
CONFIGRET Status = CR_SUCCESS;
RESOURCEID Res;
RES_DES ResDes, ResDesTemp;
ULONG ulSize, ulTestEnd, ulTestVal, ulTestLen, ulFlags;
LPBYTE pData = NULL;
BOOL bMatch = FALSE;
//
// Test whether the specified values match any values of that resource
// type in the log conf.
//
// BUGBUG - this should really do a range intersection test, since
// the allocated values may have complex intersections with the
// test values. For now I'll just illimiate simple duplications.
//
Status = CM_Get_Next_Res_Des(&ResDes, AllocLC, ResType, &Res, 0);
while (Status == CR_SUCCESS) {
//
// Get res des data
//
if (CM_Get_Res_Des_Data_Size(&ulSize, ResDes, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(ResDes);
break;
}
pData = malloc(ulSize);
if (pData == NULL) {
CM_Free_Res_Des_Handle(ResDes);
break;
}
if (CM_Get_Res_Des_Data(ResDes, pData, ulSize, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(ResDes);
free(pData);
break;
}
GetHdrValues(pData, ResType, &ulTestVal, &ulTestLen,
&ulTestEnd, &ulFlags);
//BUGBUG - do beter intersection testing here
//
// If the test values interest with the allocated values,
//
if ((ulVal == ulTestVal) && (ulLen == ulTestLen)) {
bMatch = TRUE;
free(pData);
goto MatchFound;
}
//
// Get next res des in log conf
//
ResDesTemp = ResDes;
Status = CM_Get_Next_Res_Des(&ResDes, ResDesTemp,
ResType, &Res, 0);
CM_Free_Res_Des_Handle(ResDesTemp);
free(pData);
}
MatchFound:
return bMatch;
} // IsInAllocValues
BOOL
DevHasKnownConfig(
IN LPDMPROP_DATA lpdmpd,
OUT PLOG_CONF pKnownLogConf,
OUT PULONG pLogConfType
)
{
if (lpdmpd == NULL ||
lpdmpd->lpdi->DevInst == 0x0 ||
pKnownLogConf == NULL) {
return FALSE;
}
*pKnownLogConf = 0;
//
// Does this devinst have a ALLOC log config?
//
if (CM_Get_First_Log_Conf(pKnownLogConf, lpdmpd->lpdi->DevInst,
ALLOC_LOG_CONF) == CR_SUCCESS) {
lpdmpd->dwFlags |= DMPROP_FLAG_DISPLAY_ALLOC;
*pLogConfType = ALLOC_LOG_CONF;
return TRUE;
}
//
// If not, then does it have a BOOT log config?
//
if (CM_Get_First_Log_Conf(pKnownLogConf, lpdmpd->lpdi->DevInst,
BOOT_LOG_CONF) == CR_SUCCESS) {
lpdmpd->dwFlags |= DMPROP_FLAG_DISPLAY_BOOT;
*pLogConfType = BOOT_LOG_CONF;
return TRUE;
}
//
// If not, then does it have a FORCED log config?
//
if (CM_Get_First_Log_Conf(pKnownLogConf, lpdmpd->lpdi->DevInst,
FORCED_LOG_CONF) == CR_SUCCESS) {
lpdmpd->dwFlags |= DMPROP_FLAG_DISPLAY_FORCED;
*pLogConfType = FORCED_LOG_CONF;
return TRUE;
}
return FALSE;
} // DevHasKnownConfig
BOOL
DevHasConfig(
DEVINST DevInst,
ULONG ulConfigType
)
{
BOOL bRet = (CM_Get_First_Log_Conf(NULL, DevInst, ulConfigType) == CR_SUCCESS);
return bRet;
} // DevHasConfig
DWORD
GetMinLCPriority(
IN LOG_CONF LogConf
)
{
return LCPRI_NORMAL; // NOT IMPLEMENTED
// should return minimum priority value from given logconf type
} // GetMinLCPriority
BOOL
bIsResourceSharable(
LOG_CONF LogConfig,
WORD wResID
)
{
BOOL bRet = FALSE;
RESOURCEID ridResType;
WORD wFlags;
// NOT IMPLEMENTED
#if 0
// Get the Flags for this setting. Assume it is NOT shareable
if (FCEGetResDes(lpbLogConfig, wResID, &ridResType) == FCE_OK)
{
if (FCEGetFlags(lpbLogConfig, wResID, &wFlags) == FCE_OK)
{
if (ridResType == ResType_IRQ)
{
bRet = wFlags & fIRQD_Share;
}
}
}
#endif
return(bRet);
} // bIsResourceSharable
BOOL
IsItemEditable (
int iItem,
DEVINST DevInst,
LOG_CONF RegLogConf
)
{
ULONG ulFirstVal, ulFirstLen;
ULONG ulNextVal, ulNextLen;
ULONG ulTempVal, ulTempLen;
BOOL bRet = FALSE;
// NOT IMPLEMENTED
#if 0
// Just a paranoia check here. This function should never be called
// without a valid lpRegLogConf.
Assert (lpRegLogConf);
// Check if there are alternative values allowed
// for this setting.
if (FCEGetFirstValue(lpdi->dnDevnode,
lpRegLogConf,
iItem,
&ulFirstVal,
&ulFirstLen) != FCE_ERROR)
{
if (FCEGetOtherValue(lpdi->dnDevnode,
lpRegLogConf,
iItem,
FALSE,
&ulNextVal,
&ulNextLen) != FCE_ERROR)
{
if ((ulFirstVal != ulNextVal) || (ulFirstLen != ulNextLen))
{
bRet = TRUE;
}
// Put the lpRegLogConfig back into the correct state
FCEGetOtherValue(lpdi->dnDevnode,
lpRegLogConf,
iItem,
TRUE,
&ulTempVal,
&ulTempLen);
}
}
#endif
bRet = TRUE; //BUGBUG
return(bRet);
} // IsItemEditable
void
GetHdrValues(
IN LPBYTE pData,
IN RESOURCEID ResType,
OUT PULONG pulValue,
OUT PULONG pulLen,
OUT PULONG pulEnd,
OUT PULONG pulFlags
)
{
switch (ResType) {
case ResType_Mem: {
PMEM_RESOURCE pMemData = (PMEM_RESOURCE)pData;
*pulValue = (ULONG)pMemData->MEM_Header.MD_Alloc_Base;
*pulLen = (ULONG)(pMemData->MEM_Header.MD_Alloc_End -
pMemData->MEM_Header.MD_Alloc_Base + 1);
*pulEnd = (ULONG)pMemData->MEM_Header.MD_Alloc_End;
*pulFlags = pMemData->MEM_Header.MD_Flags;
break;
}
case ResType_IO: {
PIO_RESOURCE pIoData = (PIO_RESOURCE)pData;
*pulValue = (ULONG)pIoData->IO_Header.IOD_Alloc_Base;
*pulLen = (ULONG)(pIoData->IO_Header.IOD_Alloc_End -
pIoData->IO_Header.IOD_Alloc_Base + 1);
*pulEnd = (ULONG)pIoData->IO_Header.IOD_Alloc_End;
*pulFlags = pIoData->IO_Header.IOD_DesFlags;
break;
}
case ResType_DMA: {
PDMA_RESOURCE pDmaData = (PDMA_RESOURCE)pData;
*pulValue = (ULONG)pDmaData->DMA_Header.DD_Alloc_Chan;
*pulLen = 1;
*pulEnd = *pulValue;
*pulFlags = pDmaData->DMA_Header.DD_Flags;
break;
}
case ResType_IRQ: {
PIRQ_RESOURCE pIrqData = (PIRQ_RESOURCE)pData;
*pulValue = (ULONG)pIrqData->IRQ_Header.IRQD_Alloc_Num;
*pulLen = 1;
*pulEnd = *pulValue;
*pulFlags = pIrqData->IRQ_Header.IRQD_Flags;
break;
}
}
return;
} // GetHdrValues
void
GetRangeValues(
IN LPBYTE pData,
IN RESOURCEID ResType,
IN ULONG ulIndex,
OUT PULONG pulValue,
OUT PULONG pulLen,
OUT PULONG pulEnd,
OUT PULONG pulFlags
)
{
switch (ResType) {
case ResType_Mem: {
PMEM_RESOURCE pMemData = (PMEM_RESOURCE)pData;
*pulValue = (DWORD)pMemData->MEM_Data[ulIndex].MR_Min;
*pulLen = pMemData->MEM_Data[ulIndex].MR_nBytes;
*pulEnd = (DWORD)pMemData->MEM_Data[ulIndex].MR_Max;
*pulFlags = pMemData->MEM_Data[ulIndex].MR_Flags;
AlignValues(pulValue, *pulLen, *pulEnd,
(DWORD)pMemData->MEM_Data[ulIndex].MR_Align);
break;
}
case ResType_IO: {
PIO_RESOURCE pIoData = (PIO_RESOURCE)pData;
*pulValue = (DWORD)pIoData->IO_Data[ulIndex].IOR_Min;
*pulLen = pIoData->IO_Data[ulIndex].IOR_nPorts;
*pulEnd = (DWORD)pIoData->IO_Data[ulIndex].IOR_Max;
*pulFlags = pIoData->IO_Data[ulIndex].IOR_RangeFlags;
AlignValues(pulValue, *pulLen, *pulEnd,
(DWORD)pIoData->IO_Data[ulIndex].IOR_Align);
break;
}
case ResType_DMA: {
PDMA_RESOURCE pDmaData = (PDMA_RESOURCE)pData;
*pulValue = (DWORD)pDmaData->DMA_Data[ulIndex].DR_Min;
*pulLen = 1;
*pulEnd = *pulValue;
*pulFlags = pDmaData->DMA_Data[ulIndex].DR_Flags;
break;
}
case ResType_IRQ: {
PIRQ_RESOURCE pIrqData = (PIRQ_RESOURCE)pData;
*pulValue = (DWORD)pIrqData->IRQ_Data[ulIndex].IRQR_Min;
*pulLen = 1;
*pulEnd = *pulValue;
*pulFlags = pIrqData->IRQ_Data[ulIndex].IRQR_Flags;
break;
}
}
return;
} // GetRangeValues
BOOL
AlignValues(
IN OUT PULONG pulValue,
IN ULONG ulLen,
IN ULONG ulEnd,
IN ULONG ulAlignment
)
{
div_t DivInfo;
ULONG NtAlign = ~ulAlignment + 1; // convert to NT format
if (NtAlign == 0 || NtAlign > ulEnd) {
return FALSE; // bogus alignment value
}
DivInfo = div(*pulValue, NtAlign);
if (DivInfo.rem == 0) {
//
// Specified value is already aligned properly.
//
return TRUE;
} else {
//
// Return the first valid aligned value.
//
*pulValue += NtAlign - DivInfo.rem;
if (*pulValue + ulLen - 1 > ulEnd) {
return FALSE;
}
}
return TRUE;
} // AlignValues
void
FormatResString(
LPTSTR lpszString,
ULONG ulVal,
ULONG ulLen,
RESOURCEID ResType
)
{
if ((ResType == ResType_DMA) || (ResType == ResType_IRQ)) {
wsprintf(lpszString, szOneDecNoConflict, ulVal);
} else if (ResType == ResType_IO) {
wsprintf(lpszString, szTwoWordHexNoConflict, (WORD)ulVal,
(WORD)(ulVal + ulLen - 1));
} else {
wsprintf(lpszString, szTwoDWordHexNoConflict, ulVal,
(ulVal + ulLen - 1));
}
} // FormatResString
BOOL
UnFormatResString(
LPTSTR lpszString,
PULONG pulVal,
PULONG pulEnd,
RESOURCEID ridResType
)
{
BOOL bRet = FALSE;
LPTSTR lpszTemp = NULL;
LPTSTR lpszTemp2 = NULL;
LPTSTR lpszCopy;
// BUGBUG - extend this to handling DWORDLONG values
//
// Allocate space for, and make a copy of the input string
//
lpszCopy = malloc((lstrlen(lpszString)+1) * sizeof(TCHAR));
if (lpszCopy == NULL) {
return FALSE;
}
lstrcpy(lpszCopy, lpszString);
//
// Locate the dash if there is one, and convert the white space prev to
// the dash to a NULL. (ie 0200 - 0400 while be 0200)
//
lpszTemp = lpszCopy;
while ((*lpszTemp != '-') && (*lpszTemp != '\0')) {
lpszTemp++; // AnsiNext BUGBUG ??
}
if (*lpszTemp != '\0') {
lpszTemp2 = lpszTemp-1;
++lpszTemp;
}
//
// Search back to set the NULL for the Value
//
if (lpszTemp2 != NULL) {
while ((*lpszTemp2 == ' ') || (*lpszTemp2 == '\t'))
lpszTemp2--; // AnsiPrev BUGBUG ??
*(lpszTemp2+1)= '\0';
}
//
// Convert the first entry
//
if (ConvertEditText(lpszCopy, pulVal, ridResType)) {
//
// If there is a second entry, convert it, otherwise assume a length
// of one.
//
if (*lpszTemp != '\0') {
if (ConvertEditText(lpszTemp, pulEnd,ridResType)) {
bRet = TRUE;
}
} else {
*pulEnd = *pulVal;
bRet = TRUE;
}
}
free(lpszCopy);
return bRet;
} // UnFormatResString
BOOL
ConvertEditText(
LPTSTR lpszConvert,
PULONG pulVal,
RESOURCEID ridResType
)
{
LPTSTR lpConvert;
if ((ridResType == ResType_Mem) || (ridResType == ResType_IO)) {
*pulVal = _tcstoul(lpszConvert, &lpConvert, (WORD)16);
} else {
*pulVal = _tcstoul(lpszConvert, &lpConvert, (WORD)10);
}
if (lpConvert == lpszConvert+lstrlen(lpszConvert)) {
return TRUE;
} else {
return FALSE;
}
} // ConvertEditText
void
WarnResSettingNotEditable(
HWND hDlg,
WORD idWarning
)
{
TCHAR szTitle[MAX_PATH];
TCHAR szMessage[MAX_PATH * 2];
//
// Give some warning Messages. If there is no logconfig,
// then we cannot edit any settings, if there is, then
// just the setting they are choosing is not editable.
//
LoadString(MyDllModuleHandle, IDS_DEVRES_NOMODIFYTITLE, szTitle, MAX_PATH);
LoadString(MyDllModuleHandle, idWarning, szMessage, MAX_PATH * 2);
MessageBox(hDlg, szMessage, szTitle, MB_OK | MB_TASKMODAL | MB_ICONEXCLAMATION);
} // WarnResSettingsNotEditable
LPVOID
GetListViewItemData(
HWND hList,
int iItem,
int iSubItem
)
{
LV_ITEM lviItem;
lviItem.mask = LVIF_PARAM;
lviItem.iItem = iItem;
lviItem.iSubItem = iSubItem;
if (ListView_GetItem(hList, &lviItem)) {
return (LPVOID)lviItem.lParam;
} else {
return NULL;
}
} // GetListViewItemData
BOOL
SaveDevResSettings(
HWND hDlg,
LPDMPROP_DATA lpdmpd,
LOG_CONF KnownLC,
ULONG KnownLCType,
LOG_CONF MatchingBasicLC,
LOG_CONF SelectedBasicLC,
BOOL bEdited
)
{
CONFIGRET Status = CR_SUCCESS;
LOG_CONF ForcedLogConf;
RES_DES ResDes, ResDesTemp, ResDes1;
RESOURCEID ResType;
ULONG ulSize = 0, ulCount = 0, i = 0, iCur = 0;
HWND hList = GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST);
LPBYTE pData = NULL;
PITEMDATA pItemData = NULL;
BOOL bRet = TRUE;
if (!bEdited || IsDlgButtonChecked(hDlg, IDC_DEVRES_USESYSSETTINGS)) {
//
// Either the Use Automatic Settings box is checked or it's
// unchecked but the user didn't change any settings. Copy the
// known log conf to to the forced log conf.
//
if (SelectedBasicLC != 0) {
//
// Either the Use Automatic Settings box is checked or it's
// unchecked but the user didn't change any settings. Save the
// current filtered/basic log conf as the forced log conf.
//
if (CM_Get_First_Log_Conf(&ForcedLogConf, lpdmpd->lpdi->DevInst,
FORCED_LOG_CONF) == CR_SUCCESS) {
// BUGBUG - delete all forced? delete Boot?
CM_Free_Log_Conf(ForcedLogConf, 0);
CM_Free_Log_Conf_Handle(ForcedLogConf);
}
CM_Add_Empty_Log_Conf(&ForcedLogConf, lpdmpd->lpdi->DevInst,
LCPRI_BOOTCONFIG,
FORCED_LOG_CONF | PRIORITY_EQUAL_FIRST);
//
// Get first res des in specified log conf
//
Status = CM_Get_Next_Res_Des(&ResDes, SelectedBasicLC, ResType_All,
&ResType, 0);
while (Status == CR_SUCCESS) {
//
// Write the first (index 0) range as the chosen forced resource
//
WriteResDesRangeToForced(ForcedLogConf, ResType, 0, ResDes);
//
// Get next res des in log conf
//
ResDesTemp = ResDes;
Status = CM_Get_Next_Res_Des(&ResDes, ResDesTemp,
ResType_All, &ResType, 0);
CM_Free_Res_Des_Handle(ResDesTemp);
}
CM_Free_Log_Conf_Handle(ForcedLogConf);
// BUGBUG NOT IMPLEMENTED
#if 0
pcData.cbSize = sizeof(PROPCHANGE_PARAMS);
pcData.dwStateChange = DICS_PROPCHANGE;
pcData.dwFlags = 0;
pcData.dwConfigID = 0L;
(lpdmpd->lpdi)->lpClassInstallParams = (LPARAM)&pcData;
(lpdmpd->lpdi)->Flags |= DI_CLASSINSTALLPARAMS;
DiCallClassInstaller(DIF_PROPERTYCHANGE, lpdmpd->lpdi);
(lpdmpd->lpdi)->lpClassInstallParams = NULL;
(lpdmpd->lpdi)->Flags &= ~DI_CLASSINSTALLPARAMS;
#endif
} else if (KnownLC != 0) {
//
// The selected resources are based on a known log conf (Boot, Forced,
// or Alloc). If the known resource is a forced lc, then we don't
// need to bother copy the forced to the same key.
//
if (KnownLCType == FORCED_LOG_CONF) {
goto Clean0;
}
if (CM_Get_First_Log_Conf(&ForcedLogConf, lpdmpd->lpdi->DevInst,
FORCED_LOG_CONF) == CR_SUCCESS) {
//
// delete the existing forced config
//
CM_Free_Log_Conf(ForcedLogConf, 0);
CM_Free_Log_Conf_Handle(ForcedLogConf);
}
CM_Add_Empty_Log_Conf(&ForcedLogConf, lpdmpd->lpdi->DevInst,
LCPRI_BOOTCONFIG, FORCED_LOG_CONF | PRIORITY_EQUAL_FIRST);
//
// Get first res des in known log conf
//
Status = CM_Get_Next_Res_Des(&ResDes, KnownLC, ResType_All, &ResType, 0);
while (Status == CR_SUCCESS) {
if (CM_Get_Res_Des_Data_Size(&ulSize, ResDes, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(ResDes);
return FALSE;
}
pData = malloc(ulSize);
if (pData == NULL) {
CM_Free_Res_Des_Handle(ResDes);
return FALSE;
}
if (CM_Get_Res_Des_Data(ResDes, pData, ulSize, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(ResDes);
free(pData);
return FALSE;
}
CM_Add_Res_Des(&ResDes1, ForcedLogConf, ResType, pData,
sizeof(IO_RESOURCE), 0);
CM_Free_Res_Des_Handle(ResDes1);
free(pData);
//
// Get next res des in log conf
//
ResDesTemp = ResDes;
Status = CM_Get_Next_Res_Des(&ResDes, ResDesTemp,
ResType_All, &ResType, 0);
CM_Free_Res_Des_Handle(ResDesTemp);
}
CM_Free_Log_Conf_Handle(ForcedLogConf);
}
} else {
//
// Either systems settings not chosen or resource where explicitly
// edited.
//
if (SelectedBasicLC != 0) {
//
// Save the custom settings
//
bRet = SaveCustomResSettings(hDlg, lpdmpd, SelectedBasicLC);
} else if (KnownLC != 0) {
//
// Save the custom settings
//
if (MatchingBasicLC != 0) {
bRet = SaveCustomResSettings(hDlg, lpdmpd, MatchingBasicLC);
}
}
}
Clean0:
;
return bRet;
} // SaveDevResSettings
BOOL
SaveCustomResSettings(
IN HWND hDlg,
LPDMPROP_DATA lpdmpd,
IN LOG_CONF LogConf
)
{
TCHAR szWarn[MAX_MSG_LEN];
TCHAR szTitle[MAX_MSG_LEN];
TCHAR szTemp[MAX_MSG_LEN];
DWORD dwPriority, dwLCPri;
LOG_CONF ForcedLogConf;
RES_DES ResDes;
HWND hList = GetDlgItem(hDlg, IDC_DEVRES_SETTINGSLIST);
PITEMDATA pItemData = NULL;
LONG iCur;
BOOL bRet = FALSE;
//
// form the "warning - do you want to continue" message
//
LoadString(MyDllModuleHandle, IDS_MAKE_FORCED_TITLE, szTitle, MAX_MSG_LEN);
LoadString(MyDllModuleHandle, IDS_FORCEDCONFIG_WARN1, szWarn, MAX_MSG_LEN);
LoadString(MyDllModuleHandle, IDS_FORCEDCONFIG_WARN2, szTemp, MAX_MSG_LEN);
lstrcat(szWarn, szTemp);
LoadString(MyDllModuleHandle, IDS_FORCEDCONFIG_WARN3, szTemp, MAX_MSG_LEN);
lstrcat(szWarn, szTemp);
//
// If the LCPRI is soft configurable, and the user chooses YES to the
// warning, then save the new config. If the LCPRI is not soft
// configurable, just save with no warning
//
dwLCPri = GetMinLCPriority(LogConf);
if (!(((dwLCPri >= LCPRI_DESIRED) && (dwLCPri <= LCPRI_LASTSOFTCONFIG)) &&
(MessageBox(hDlg, szWarn, szTitle, MB_YESNO|MB_ICONEXCLAMATION) == IDNO))) {
//
// We're still using the selected basic LC, but use the range index
// imbedded in the listview control
// BUGBUG - also need to check the value to see if a user
// overrode it (is this possible?)
//
bRet = TRUE;
if (CM_Get_First_Log_Conf(&ForcedLogConf, lpdmpd->lpdi->DevInst,
FORCED_LOG_CONF) == CR_SUCCESS) {
CM_Free_Log_Conf(ForcedLogConf, 0);
CM_Free_Log_Conf_Handle(ForcedLogConf);
}
//
// Save the current choices as the forced config
//
CM_Add_Empty_Log_Conf(&ForcedLogConf, lpdmpd->lpdi->DevInst, LCPRI_BOOTCONFIG,
FORCED_LOG_CONF | PRIORITY_EQUAL_FIRST);
iCur = (int)ListView_GetNextItem(hList, -1, LVNI_ALL);
while (iCur != -1) {
pItemData = (PITEMDATA)GetListViewItemData(hList, iCur, 0);
if (pItemData) {
// retrieve values
if (GetMatchingResDes(pItemData->ulValue,
pItemData->ulLen,
pItemData->ulEnd,
pItemData->ResType,
LogConf,
&ResDes)) {
//
// Write the first range as the chosen forced resource
//
WriteValuesToForced(ForcedLogConf, pItemData->ResType,
pItemData->RangeCount, ResDes,
pItemData->ulValue,
pItemData->ulLen,
pItemData->ulEnd);
}
}
iCur = (int)ListView_GetNextItem(hList, iCur, LVNI_ALL);
}
CM_Free_Log_Conf_Handle(ForcedLogConf);
#if 0
// if we wrote out the forced config successfully
pcData.cbSize = sizeof(PROPCHANGE_PARAMS);
pcData.dwStateChange = DICS_PROPCHANGE;
pcData.dwFlags = 0;
pcData.dwConfigID = 0L;
(lpdmpd->lpdi)->lpClassInstallParams = (LPARAM)&pcData;
(lpdmpd->lpdi)->Flags |= (DI_CLASSINSTALLPARAMS | DI_NODI_DEFAULTACTION);
// Give the class installer a crack at the propchange process
DiCallClassInstaller(DIF_PROPERTYCHANGE, lpdmpd->lpdi);
(lpdmpd->lpdi)->lpClassInstallParams = NULL;
(lpdmpd->lpdi)->Flags &= ~(DI_CLASSINSTALLPARAMS | DI_NODI_DEFAULTACTION);
// Check the Priority of this LC. If it is greater
// than LCPRI_LASTSOFTCONFIG, then we need to reboot
// otherwise try the dynamic changestate route.
dwPriority = DWORD_AT((LPBYTE)lpRegLogConf+sizeof(DWORD));
if (dwPriority <= LCPRI_LASTSOFTCONFIG) {
// Do the default action for SoftConfigable devices, which
// will attempt to restart the device with the new config
// This could take a while so use an hourglass
SetCursor(LoadCursor(NULL, IDC_WAIT));
DiChangeState(lpdmpd->lpdi, DICS_PROPCHANGE, 0, 0);
SetCursor(LoadCursor(NULL, IDC_ARROW));
} else if ((dwPriority > LCPRI_LASTSOFTCONFIG) &&
(dwPriority <= LCPRI_RESTART)) {
lpdmpd->lpdi->Flags |= DI_NEEDRESTART;
} else {
lpdmpd->lpdi->Flags |= DI_NEEDREBOOT;
// Set hardreconfig flag if user needs to change hardware jumpers
if (dwPriority >= LCPRI_HARDRECONFIG)
*((LPDWORD)(lpdmpd->psp.lParam)) |= PROPCHG_FLAG_SHUTDOWN;
}
#endif
lpdmpd->dwFlags |= DMPROP_FLAG_CHANGESSAVED;
#if 0
// Properites have changed, so set this flag to re-init the DM UI
(lpdmpd->lpdi)->Flags |= DI_PROPERTIES_CHANGE;
#endif
}
return bRet;
} // SaveCustomResSettings
BOOL
WriteResDesRangeToForced(
IN LOG_CONF ForcedLogConf,
IN RESOURCEID ResType,
IN ULONG RangeIndex,
IN RES_DES RD
)
{
RES_DES ResDes;
ULONG ulSize;
LPBYTE pData = NULL;
if (CM_Get_Res_Des_Data_Size(&ulSize, RD, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(RD);
return FALSE;
}
pData = malloc(ulSize);
if (pData == NULL) {
CM_Free_Res_Des_Handle(RD);
return FALSE;
}
if (CM_Get_Res_Des_Data(RD, pData, ulSize, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(RD);
free(pData);
return FALSE;
}
//
// convert the first range data into hdr data
//
switch (ResType) {
case ResType_Mem: {
PMEM_RESOURCE pMemData = (PMEM_RESOURCE)pData;
PMEM_RESOURCE pForced = (PMEM_RESOURCE)malloc(sizeof(MEM_RESOURCE));
pForced->MEM_Header.MD_Count = 0;
pForced->MEM_Header.MD_Type = MType_Range;
pForced->MEM_Header.MD_Alloc_Base = pMemData->MEM_Data[RangeIndex].MR_Min;
pForced->MEM_Header.MD_Alloc_End = pMemData->MEM_Data[RangeIndex].MR_Min +
pMemData->MEM_Data[RangeIndex].MR_nBytes - 1;
pForced->MEM_Header.MD_Flags = pMemData->MEM_Data[RangeIndex].MR_Flags;
pForced->MEM_Header.MD_Reserved = 0;
CM_Add_Res_Des(&ResDes, ForcedLogConf, ResType_Mem, pForced,
sizeof(MEM_RESOURCE), 0);
CM_Free_Res_Des_Handle(ResDes);
free(pForced);
break;
}
case ResType_IO: {
PIO_RESOURCE pIoData = (PIO_RESOURCE)pData;
PIO_RESOURCE pForced = (PIO_RESOURCE)malloc(sizeof(IO_RESOURCE));
pForced->IO_Header.IOD_Count = 0;
pForced->IO_Header.IOD_Type = IOType_Range;
pForced->IO_Header.IOD_Alloc_Base = pIoData->IO_Data[RangeIndex].IOR_Min;
pForced->IO_Header.IOD_Alloc_End = pIoData->IO_Data[RangeIndex].IOR_Min +
pIoData->IO_Data[RangeIndex].IOR_nPorts - 1;
pForced->IO_Header.IOD_DesFlags = pIoData->IO_Data[RangeIndex].IOR_RangeFlags;
CM_Add_Res_Des(&ResDes, ForcedLogConf, ResType_IO, pForced,
sizeof(IO_RESOURCE), 0);
CM_Free_Res_Des_Handle(ResDes);
free(pForced);
break;
}
case ResType_DMA: {
PDMA_RESOURCE pDmaData = (PDMA_RESOURCE)pData;
PDMA_RESOURCE pForced = (PDMA_RESOURCE)malloc(sizeof(DMA_RESOURCE));
pForced->DMA_Header.DD_Count = 0;
pForced->DMA_Header.DD_Type = DType_Range;
pForced->DMA_Header.DD_Flags = pDmaData->DMA_Data[RangeIndex].DR_Flags;
pForced->DMA_Header.DD_Alloc_Chan = pDmaData->DMA_Data[RangeIndex].DR_Min;
CM_Add_Res_Des(&ResDes, ForcedLogConf, ResType_DMA, pForced,
sizeof(DMA_RESOURCE), 0);
CM_Free_Res_Des_Handle(ResDes);
free(pForced);
break;
}
case ResType_IRQ: {
PIRQ_RESOURCE pIrqData = (PIRQ_RESOURCE)pData;
PIRQ_RESOURCE pForced = (PIRQ_RESOURCE)malloc(sizeof(IRQ_RESOURCE));
pForced->IRQ_Header.IRQD_Count = 0;
pForced->IRQ_Header.IRQD_Type = IRQType_Range;
pForced->IRQ_Header.IRQD_Flags = pIrqData->IRQ_Data[RangeIndex].IRQR_Flags;
pForced->IRQ_Header.IRQD_Alloc_Num = pIrqData->IRQ_Data[RangeIndex].IRQR_Min;
CM_Add_Res_Des(&ResDes, ForcedLogConf, ResType_IRQ, pForced,
sizeof(IRQ_RESOURCE), 0);
CM_Free_Res_Des_Handle(ResDes);
free(pForced);
break;
}
}
return TRUE;
} // WriteResDesRangeToForced
BOOL
WriteValuesToForced(
IN LOG_CONF ForcedLogConf,
IN RESOURCEID ResType,
IN ULONG RangeIndex,
IN RES_DES RD,
IN ULONG ulValue,
IN ULONG ulLen,
IN ULONG ulEnd
)
{
RES_DES ResDes;
ULONG ulSize;
LPBYTE pData = NULL;
if (CM_Get_Res_Des_Data_Size(&ulSize, RD, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(RD);
return FALSE;
}
pData = malloc(ulSize);
if (pData == NULL) {
CM_Free_Res_Des_Handle(RD);
return FALSE;
}
if (CM_Get_Res_Des_Data(RD, pData, ulSize, 0) != CR_SUCCESS) {
CM_Free_Res_Des_Handle(RD);
free(pData);
return FALSE;
}
//
// convert the first range data into hdr data
//
switch (ResType) {
case ResType_Mem: {
PMEM_RESOURCE pMemData = (PMEM_RESOURCE)pData;
PMEM_RESOURCE pForced = (PMEM_RESOURCE)malloc(sizeof(MEM_RESOURCE));
pForced->MEM_Header.MD_Count = 0;
pForced->MEM_Header.MD_Type = MType_Range;
pForced->MEM_Header.MD_Alloc_Base = ulValue;
pForced->MEM_Header.MD_Alloc_End = ulEnd;
pForced->MEM_Header.MD_Flags = pMemData->MEM_Data[RangeIndex].MR_Flags;
pForced->MEM_Header.MD_Reserved = 0;
CM_Add_Res_Des(&ResDes, ForcedLogConf, ResType_Mem, pForced,
sizeof(MEM_RESOURCE), 0);
CM_Free_Res_Des_Handle(ResDes);
free(pForced);
break;
}
case ResType_IO: {
PIO_RESOURCE pIoData = (PIO_RESOURCE)pData;
PIO_RESOURCE pForced = (PIO_RESOURCE)malloc(sizeof(IO_RESOURCE));
pForced->IO_Header.IOD_Count = 0;
pForced->IO_Header.IOD_Type = IOType_Range;
pForced->IO_Header.IOD_Alloc_Base = ulValue;
pForced->IO_Header.IOD_Alloc_End = ulEnd;
pForced->IO_Header.IOD_DesFlags = pIoData->IO_Data[RangeIndex].IOR_RangeFlags;
CM_Add_Res_Des(&ResDes, ForcedLogConf, ResType_IO, pForced,
sizeof(IO_RESOURCE), 0);
CM_Free_Res_Des_Handle(ResDes);
free(pForced);
break;
}
case ResType_DMA: {
PDMA_RESOURCE pDmaData = (PDMA_RESOURCE)pData;
PDMA_RESOURCE pForced = (PDMA_RESOURCE)malloc(sizeof(DMA_RESOURCE));
pForced->DMA_Header.DD_Count = 0;
pForced->DMA_Header.DD_Type = DType_Range;
pForced->DMA_Header.DD_Flags = pDmaData->DMA_Data[RangeIndex].DR_Flags;
pForced->DMA_Header.DD_Alloc_Chan = ulValue;
CM_Add_Res_Des(&ResDes, ForcedLogConf, ResType_DMA, pForced,
sizeof(DMA_RESOURCE), 0);
CM_Free_Res_Des_Handle(ResDes);
free(pForced);
break;
}
case ResType_IRQ: {
PIRQ_RESOURCE pIrqData = (PIRQ_RESOURCE)pData;
PIRQ_RESOURCE pForced = (PIRQ_RESOURCE)malloc(sizeof(IRQ_RESOURCE));
pForced->IRQ_Header.IRQD_Count = 0;
pForced->IRQ_Header.IRQD_Type = IRQType_Range;
pForced->IRQ_Header.IRQD_Flags = pIrqData->IRQ_Data[RangeIndex].IRQR_Flags;
pForced->IRQ_Header.IRQD_Alloc_Num = ulValue;
CM_Add_Res_Des(&ResDes, ForcedLogConf, ResType_IRQ, pForced,
sizeof(IRQ_RESOURCE), 0);
CM_Free_Res_Des_Handle(ResDes);
free(pForced);
break;
}
}
return TRUE;
} // WriteValuesToForced
//---------------------------------------------------------------------------
// Edit Resource Dialog Box
//---------------------------------------------------------------------------
BOOL
WINAPI
EditResourceDlgProc(
HWND hDlg,
UINT wMsg,
WPARAM wParam,
LPARAM lParam
)
{
TCHAR szBuffer[MAX_PATH];
static ULONG ulEditedValue, ulEditedLen, ulEditedEnd;
switch (wMsg) {
case WM_INITDIALOG: {
PRESOURCEEDITINFO lprei = (PRESOURCEEDITINFO)lParam;
ULONG ulSize = 0;
SetWindowLong(hDlg, DWL_USER, lParam); // save for later msgs
lprei->dwFlags &= ~REI_FLAGS_CONFLICT; // no conflict yet
lprei->dwFlags |= REI_FLAG_NONUSEREDIT; // no manual edits yet
ulEditedValue = lprei->ulCurrentVal;
ulEditedLen = lprei->ulCurrentLen;
ulEditedEnd = lprei->ulCurrentEnd;
InitEditResDlg(hDlg, lprei, ulEditedValue, ulEditedLen);
//
// locate the range index that matches the current values
//
lprei->ulRangeCount = 0;
lprei->ulRangeCount = LocateValues(lprei->pData, lprei->ridResType,
ulEditedValue, ulEditedLen,
ulEditedEnd);
SetFocus(GetDlgItem(hDlg, IDC_EDITRES_VALUE));
break; // return default (FALSE) to indicate we've set focus
}
case WM_NOTIFY: {
PRESOURCEEDITINFO lprei = (PRESOURCEEDITINFO)GetWindowLong(hDlg, DWL_USER);
LPNM_UPDOWN lpnm = (LPNM_UPDOWN)lParam;
switch (lpnm->hdr.code) {
case UDN_DELTAPOS:
if (lpnm->hdr.idFrom == IDC_EDITRES_SPIN) {
if (lpnm->iDelta > 0) {
GetOtherValues(lprei->pData, lprei->ridResType, +1,
&lprei->ulRangeCount,
&ulEditedValue,
&ulEditedLen,
&ulEditedEnd);
} else {
GetOtherValues(lprei->pData, lprei->ridResType, -1,
&lprei->ulRangeCount,
&ulEditedValue,
&ulEditedLen,
&ulEditedEnd);
}
FormatResString(szBuffer, ulEditedValue, ulEditedLen,
lprei->ridResType);
lprei->dwFlags |= REI_FLAG_NONUSEREDIT;
SetDlgItemText(hDlg, IDC_EDITRES_VALUE, szBuffer);
UpdateEditResConflictList(hDlg, lprei,
ulEditedValue,
ulEditedLen,
lprei->ulCurrentFlags);
}
break;
}
break;
}
case WM_COMMAND: {
switch(LOWORD(wParam)) {
case IDOK: {
PRESOURCEEDITINFO lprei = (PRESOURCEEDITINFO) GetWindowLong(hDlg, DWL_USER);
//
// Validate the values (could have been manually edited)
//
if (bValidateResourceVal(hDlg, &ulEditedValue, &ulEditedLen,
&ulEditedEnd, lprei)) {
//
// Warn if there is a conflict. If use accepts conflict
// end the dialog, otherwise update the
// edit control since it may have been changed by the
// Validate call.
//
if(bConflictWarn(hDlg, ulEditedValue, ulEditedLen,
ulEditedEnd, lprei)) {
lprei->ulCurrentVal = ulEditedValue;
lprei->ulCurrentLen = ulEditedLen;
lprei->ulCurrentEnd = ulEditedEnd;
EndDialog(hDlg, IDOK);
if (lprei->pData) {
free(lprei->pData);
}
} else {
//
// Format and display the data
//
FormatResString(szBuffer, ulEditedValue, ulEditedLen, lprei->ridResType);
SetDlgItemText(hDlg, IDC_EDITRES_VALUE, szBuffer);
}
}
return TRUE;
}
case IDCANCEL: {
PRESOURCEEDITINFO lprei = (PRESOURCEEDITINFO)GetWindowLong(hDlg, DWL_USER);
if (lprei->pData) {
free(lprei->pData);
}
EndDialog(hDlg, FALSE);
return TRUE;
}
case IDC_EDITRES_VALUE: {
switch (HIWORD(wParam)) {
case EN_CHANGE: {
PRESOURCEEDITINFO lprei = (PRESOURCEEDITINFO)GetWindowLong(hDlg, DWL_USER);
// If Non user edit, then clear the flag, else
// clear the conflict list, since we are unsure
// of what the user has entered at this time
if (lprei->dwFlags & REI_FLAG_NONUSEREDIT) {
lprei->dwFlags &= ~REI_FLAG_NONUSEREDIT;
} else {
ClearEditResConflictList(hDlg, CEF_UNKNOWN);
}
break;
}
// If the edit control looses focus, then we should
// validte the contents
case EN_KILLFOCUS: {
}
break;
}
break;
}
}
break;
}
#if 0
case WM_HELP: // F1
WinHelp(((LPHELPINFO)lParam)->hItemHandle, szHelpfile, HELP_WM_HELP, (DWORD)(LPSTR)aProfileIds);
break;
case WM_CONTEXTMENU: // right mouse click
WinHelp((HWND)wParam, szHelpfile, HELP_CONTEXTMENU, (DWORD)(LPSTR)aProfileIds);
break;
#endif
}
return FALSE;
} // EditResourceDlgProc
void
InitEditResDlg(
HWND hDlg,
PRESOURCEEDITINFO lprei,
ULONG ulVal,
ULONG ulLen
)
{
TCHAR szBuffer[MAX_PATH], szInstr[MAX_PATH], szTemp[MAX_PATH],
szResType[MAX_PATH], szResTypeLC[MAX_PATH];
ULONG ulSize = 0;
//
// Set the initial Value
//
FormatResString(szBuffer, ulVal, ulLen, lprei->ridResType);
SetDlgItemText(hDlg, IDC_EDITRES_VALUE, szBuffer);
//
// Setup the Spinner
//
SendDlgItemMessage(hDlg, IDC_EDITRES_SPIN, UDM_SETRANGE, 0, MAKELONG(MAX_SPINRANGE, 0));
SendDlgItemMessage(hDlg, IDC_EDITRES_SPIN, UDM_SETPOS, 0, MAKELONG(0,0));
SendDlgItemMessage(hDlg, IDC_EDITRES_SPIN, UDM_SETACCEL, 5, (LONG)(LPUDACCEL)udAccel);
//
// Limit the Edit Text.
//
switch (lprei->ridResType) {
case ResType_Mem:
LoadString(MyDllModuleHandle, IDS_MEMORY_FULL, szResType, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_MEMORY_FULL_LC, szResTypeLC, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_EDITRES_RANGEINSTR1, szInstr, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_EDITRES_RANGEINSTR2, szTemp, MAX_PATH);
lstrcat(szInstr, szTemp);
//
// Limit the Input field to Start Val (8) + End Val(8) + seperator (4)
//
SendDlgItemMessage(hDlg, IDC_EDITRES_VALUE, EM_LIMITTEXT, 20, 0l);
break;
case ResType_IO:
LoadString(MyDllModuleHandle, IDS_IO_FULL, szResType, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_EDITRES_RANGEINSTR1, szInstr, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_EDITRES_RANGEINSTR2, szTemp, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_IO_FULL_LC, szResTypeLC, MAX_PATH);
lstrcat(szInstr, szTemp);
//
// Limit the Input field to Start Val (4) + End Val(4) + seperator (4)
//
SendDlgItemMessage(hDlg, IDC_EDITRES_VALUE, EM_LIMITTEXT, 12, 0l);
break;
case ResType_DMA:
LoadString(MyDllModuleHandle, IDS_DMA_FULL, szResType, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_EDITRES_SINGLEINSTR1, szInstr, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_EDITRES_SINGLEINSTR2, szTemp, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_DMA_FULL_LC, szResTypeLC, MAX_PATH);
lstrcat(szInstr, szTemp);
//
// Limit the Input field to Val (2)
//
SendDlgItemMessage(hDlg, IDC_EDITRES_VALUE, EM_LIMITTEXT, 2, 0l);
break;
case ResType_IRQ:
LoadString(MyDllModuleHandle, IDS_IRQ_FULL, szResType, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_EDITRES_SINGLEINSTR1, szInstr, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_EDITRES_SINGLEINSTR2, szTemp, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_IRQ_FULL_LC, szResTypeLC, MAX_PATH);
lstrcat(szInstr, szTemp);
//
// Limit the Input field to Val (2)
//
SendDlgItemMessage(hDlg, IDC_EDITRES_VALUE, EM_LIMITTEXT, 2, 0l);
break;
}
//
// Set the Instruction Text
//
wsprintf(szBuffer, szInstr, szResTypeLC);
SetDlgItemText(hDlg, IDC_EDITRES_INSTRUCTIONS, szBuffer);
//
// Set the Dialog Title
//
LoadString(MyDllModuleHandle, IDS_EDITRES_TITLE, szTemp, MAX_PATH);
wsprintf(szBuffer, szTemp, szResType);
SetWindowText(hDlg, szBuffer);
//
// If this is a MF parent device, then show which children own this resource.
//
UpdateMFChildList(hDlg, lprei);
//
// Read the res des data and store a ptr to it so we
// don't have to refetch it multiple times.
//
lprei->pData = NULL;
if (CM_Get_Res_Des_Data_Size(&ulSize, lprei->ResDes, 0) == CR_SUCCESS) {
lprei->pData = malloc(ulSize);
if (lprei->pData != NULL) {
CM_Get_Res_Des_Data(lprei->ResDes, lprei->pData, ulSize, 0);
}
}
//
// Update the Conflict List.
//
UpdateEditResConflictList(hDlg, lprei, ulVal, ulLen, lprei->ulCurrentFlags);
} // InitEditResDlg
void
UpdateMFChildList(
HWND hDlg,
PRESOURCEEDITINFO lprei
)
{
UNREFERENCED_PARAMETER(hDlg);
UNREFERENCED_PARAMETER(lprei);
//
// See if this is a MF parent device. Check for a Child0000 subkey
//
// NOT IMPLEMENTED, SEE WINDOWS 95 SOURCES.
//
} // UpdateMFChildList
void
ClearEditResConflictList(
HWND hDlg,
DWORD dwFlags
)
{
HWND hwndConflictList = GetDlgItem(hDlg, IDC_EDITRES_CONFLICTLIST);
TCHAR szBuffer[MAX_PATH];
//
// Clear the Conflict list to start.
//
SendMessage(hwndConflictList, LB_RESETCONTENT, 0, 0L);
//
// If we are in minimal windows, this is easy, since we cannot
// show conflict info.
//
if (g_bMinWin) {
//
// If there is no devnodes, then we cannot show any conflict info.
//
LoadString(MyDllModuleHandle, IDS_DEVRES_NOCONFLICTINFO, szBuffer, MAX_PATH);
SetDlgItemText(hDlg, IDC_EDITRES_CONFLICTTEXT, szBuffer);
EnableWindow(hwndConflictList, FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_EDITRES_CONFLICTDEVTITLE), FALSE);
return;
}
//
// Load and set the info text string
//
if (dwFlags & CEF_UNKNOWN) {
LoadString(MyDllModuleHandle, IDS_EDITRES_UNKNOWNCONFLICT, szBuffer, MAX_PATH);
} else {
LoadString(MyDllModuleHandle, IDS_EDITRES_NOCONFLICT, szBuffer, MAX_PATH);
}
SetDlgItemText(hDlg, IDC_EDITRES_CONFLICTTEXT, szBuffer);
//
// Load and set the List string
//
if (dwFlags & CEF_UNKNOWN) {
LoadString(MyDllModuleHandle, IDS_EDITRES_UNKNOWNCONFLICTINGDEVS, szBuffer, MAX_PATH);
} else {
LoadString(MyDllModuleHandle, IDS_EDITRES_NOCONFLICTINGDEVS, szBuffer, MAX_PATH);
}
SendMessage(hwndConflictList, LB_ADDSTRING, 0, (LPARAM)(LPSTR)szBuffer);
} // ClearEditResConflictList
void
UpdateEditResConflictList(
HWND hDlg,
PRESOURCEEDITINFO lprei,
ULONG ulVal,
ULONG ulLen,
ULONG ulFlags
)
{
HWND hwndConflictList = GetDlgItem(hDlg, IDC_EDITRES_CONFLICTLIST);
BOOL bConflict = FALSE;
LPBYTE pResourceData = NULL;
TCHAR szBuffer[MAX_PATH];
ULONG ulSize = 0;
//
// Clean out the Conflict list to start.
//
SendMessage(hwndConflictList, LB_RESETCONTENT, 0, 0L);
//
// Special case - if an ALLOC config exists, check these values
// against the ALLOC config first, before checking if a conflict
// exists (otherwise we may detect a conflict with ourselves).
//
if (lprei->AllocLC != 0) {
if (IsInAllocValues(lprei->AllocLC, lprei->ridResType, ulVal, ulLen)) {
lprei->dwFlags &= ~REI_FLAGS_CONFLICT;
LoadString(MyDllModuleHandle, IDS_EDITRES_NOCONFLICT, szBuffer, MAX_PATH);
SetDlgItemText(hDlg, IDC_EDITRES_CONFLICTTEXT, szBuffer);
LoadString(MyDllModuleHandle, IDS_EDITRES_NOCONFLICTINGDEVS, szBuffer, MAX_PATH);
SendMessage(hwndConflictList, LB_ADDSTRING, 0, (LPARAM)(LPSTR)szBuffer);
return;
}
}
//
// If we are in minimal windows, this is easy, since we cannot
// show conflict info (i.e., ff there is no devnodes, then we cannot
// show any conflict info).
//
if (g_bMinWin) {
LoadString(MyDllModuleHandle, IDS_DEVRES_NOCONFLICTINFO, szBuffer, MAX_PATH);
SetDlgItemText(hDlg, IDC_EDITRES_CONFLICTTEXT, szBuffer);
EnableWindow(hwndConflictList, FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_EDITRES_CONFLICTDEVTITLE), FALSE);
return;
}
//
// Windows 95 can retrieve a list of conflicting devices, for now we
// just indicate if there's a conflict or not.
//
if (MakeResourceData(&pResourceData, &ulSize, lprei->ridResType,
ulVal, ulLen, ulFlags)) {
if (CM_Detect_Resource_Conflict(lprei->lpdi->DevInst,
lprei->ridResType,
pResourceData,
ulSize,
&bConflict,
0) != CR_SUCCESS) {
//
// An error occured, we don't know if a conflict occured or not.
//
LoadString(MyDllModuleHandle, IDS_EDITRES_UNKNOWNCONFLICT, szBuffer, MAX_PATH);
SetDlgItemText(hDlg, IDC_EDITRES_CONFLICTTEXT, szBuffer);
LoadString(MyDllModuleHandle, IDS_EDITRES_UNKNOWNCONFLICTINGDEVS, szBuffer, MAX_PATH);
SendMessage(hwndConflictList, LB_ADDSTRING, 0, (LPARAM)(LPSTR)szBuffer);
} else if (bConflict) {
//
// The resource conflicts with another unknown device.
//
lprei->dwFlags |= REI_FLAGS_CONFLICT;
LoadString(MyDllModuleHandle, IDS_EDITRES_DEVCONFLICT, szBuffer, MAX_PATH);
SetDlgItemText(hDlg, IDC_EDITRES_CONFLICTTEXT, szBuffer);
LoadString(MyDllModuleHandle, IDS_EDITRES_UNKNOWNCONFLICTINGDEVS, szBuffer, MAX_PATH);
SendMessage(hwndConflictList, LB_ADDSTRING, 0, (LPARAM)(LPSTR)szBuffer);
} else {
//
// The resource does not conflict with any other devices.
//
lprei->dwFlags &= ~REI_FLAGS_CONFLICT;
LoadString(MyDllModuleHandle, IDS_EDITRES_NOCONFLICT, szBuffer, MAX_PATH);
SetDlgItemText(hDlg, IDC_EDITRES_CONFLICTTEXT, szBuffer);
LoadString(MyDllModuleHandle, IDS_EDITRES_NOCONFLICTINGDEVS, szBuffer, MAX_PATH);
SendMessage(hwndConflictList, LB_ADDSTRING, 0, (LPARAM)(LPSTR)szBuffer);
}
free(pResourceData);
} else {
//
// An error occured, we don't know if a conflict occured or not.
//
LoadString(MyDllModuleHandle, IDS_EDITRES_UNKNOWNCONFLICT, szBuffer, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_EDITRES_UNKNOWNCONFLICTINGDEVS, szBuffer, MAX_PATH);
SendMessage(hwndConflictList, LB_ADDSTRING, 0, (LPARAM)(LPSTR)szBuffer);
}
#if 0
SendMessage(hwndConflictList, LB_ADDSTRING, 0, (LPARAM)(LPSTR)lpdiTemp->szDescription);
#endif
return;
} // UpdateEditResConflictList
ULONG
LocateValues(
IN LPBYTE pData,
IN RESOURCEID ResType,
IN ULONG ulCurrentValue,
IN ULONG ulCurrentLen,
IN ULONG ulCurrentEnd
)
{
PGENERIC_RESOURCE pGenRes = (PGENERIC_RESOURCE)pData;
ULONG ulIndex = 0, ulValue = 0, ulLen = 0, ulEnd = 0, ulFlags = 0;
//
// Figure out which index the current values correspond to
//
for (ulIndex = 0; ulIndex < pGenRes->GENERIC_Header.GENERIC_Count; ulIndex++) {
GetRangeValues(pData, ResType, ulIndex, &ulValue, &ulLen, &ulEnd, &ulFlags);
if ((ulCurrentLen == ulLen) &&
(ulCurrentValue >= ulValue) &&
(ulCurrentEnd <= ulEnd)) {
goto FoundValue;
}
}
ulIndex = 0xFFFFFFFF;
FoundValue:
return ulIndex;
} // LocateValues
void
GetOtherValues(
IN LPBYTE pData,
IN RESOURCEID ResType,
IN LONG Increment,
IN OUT PULONG pulIndex,
IN OUT PULONG pulValue,
IN OUT PULONG pulLen,
IN OUT PULONG pulEnd
)
{
PGENERIC_RESOURCE pGenRes = (PGENERIC_RESOURCE)pData;
ULONG ulFlags = 0;
if (Increment == 1) {
//
// Get the "next" values
//
// See if there's another valid value within this range before
// skipping to the next range.
//
if (!GetNextAlignedValue(pData, ResType, *pulIndex,
pulValue, pulLen, pulEnd)) {
(*pulIndex)++;
if (*pulIndex >= pGenRes->GENERIC_Header.GENERIC_Count) {
*pulIndex = 0;
}
GetRangeValues(pData, ResType, *pulIndex, pulValue, pulLen, pulEnd, &ulFlags);
}
} else if (Increment == -1) {
//
// Get the "previous" values
//
// See if there's another valid value within this range before
// going to the previous range.
//
if (!GetPreviousAlignedValue(pData, ResType, *pulIndex,
pulValue, pulLen, pulEnd)) {
//
// This is the first valid value in this range, use the last valid
// value of the previous range (if any).
//
if (*pulIndex == 0) {
*pulIndex = pGenRes->GENERIC_Header.GENERIC_Count - 1;
} else {
(*pulIndex)--;
}
GetRangeValues(pData, ResType, *pulIndex, pulValue, pulLen, pulEnd, &ulFlags);
while (GetNextAlignedValue(pData, ResType, *pulIndex,
pulValue, pulLen, pulEnd)) {
; // skip to last valid value for this range
}
}
}
return;
} // GetOtherValues
BOOL
GetNextAlignedValue(
IN LPBYTE pData,
IN RESOURCEID ResType,
IN ULONG ulIndex,
IN OUT PULONG pulValue,
IN OUT PULONG pulLen,
IN OUT PULONG pulEnd
)
{
ULONG Value, ulFlags, RangeValue, RangeLen, RangeEnd;
//
// Get the values for this range.
//
GetRangeValues(pData, ResType, ulIndex, &RangeValue, &RangeLen,
&RangeEnd, &ulFlags);
if (*pulValue + *pulLen >= RangeEnd) {
return FALSE; // no other values in this range
}
//
// Skip to next valid value within this range, taking care of any
// alignment restrictions.
//
Value = *pulValue;
Value++;
switch (ResType) {
case ResType_Mem: {
PMEM_RESOURCE pMemData = (PMEM_RESOURCE)pData;
AlignValues(&Value, RangeLen, RangeEnd,
(DWORD)pMemData->MEM_Data[ulIndex].MR_Align);
break;
}
case ResType_IO: {
PIO_RESOURCE pIoData = (PIO_RESOURCE)pData;
AlignValues(&Value, RangeLen, RangeEnd,
(DWORD)pIoData->IO_Data[ulIndex].IOR_Align);
break;
}
default:
break;
}
if (Value + RangeLen - 1 > RangeEnd) {
return FALSE;
}
*pulValue = Value;
return TRUE;
} // GetNextAlignedValue
BOOL
GetPreviousAlignedValue(
IN LPBYTE pData,
IN RESOURCEID ResType,
IN ULONG ulIndex,
IN OUT PULONG pulValue,
IN OUT PULONG pulLen,
IN OUT PULONG pulEnd
)
{
ULONG Value, ulFlags, RangeValue, RangeLen, RangeEnd;
//
// Get the values for this range.
//
GetRangeValues(pData, ResType, ulIndex, &RangeValue, &RangeLen,
&RangeEnd, &ulFlags);
if (*pulValue <= RangeValue) {
return FALSE; // no other values in this range
}
//
// Skip to previous valid value within this range.
//
Value = *pulValue;
//
// Take care of alignment restrictions
//
switch (ResType) {
case ResType_Mem: {
PMEM_RESOURCE pMemData = (PMEM_RESOURCE)pData;
if (AlignValues(&Value, RangeLen, RangeEnd,
(DWORD)pMemData->MEM_Data[ulIndex].MR_Align)) {
Value -= ~(DWORD)pMemData->MEM_Data[ulIndex].MR_Align + 1;
}
break;
}
case ResType_IO: {
PIO_RESOURCE pIoData = (PIO_RESOURCE)pData;
if (AlignValues(&Value, RangeLen, RangeEnd,
(DWORD)pIoData->IO_Data[ulIndex].IOR_Align)) {
Value -= ~(DWORD)pIoData->IO_Data[ulIndex].IOR_Align + 1;
}
break;
}
case ResType_DMA:
Value--;
break;
case ResType_IRQ:
Value--;
break;
}
if (Value < RangeValue) {
return FALSE;
}
*pulValue = Value;
return TRUE;
} // GetPreviousAlignedValue
BOOL
bValidateResourceVal(
HWND hDlg,
PULONG pulVal,
PULONG pulLen,
PULONG pulEnd,
PRESOURCEEDITINFO lprei
)
{
TCHAR szSetting[MAX_VAL_LEN], szNewSetting[MAX_VAL_LEN];
TCHAR szMessage[MAX_MSG_LEN], szTemp[MAX_MSG_LEN], szTemp1[MAX_MSG_LEN];
TCHAR szTitle[MAX_PATH];
ULONG ulVal, ulEnd, ulLen, ulFlags, ResIndex;
ULONG ulValidVal, ulValidLen, ulValidEnd;
BOOL bRet;
GetDlgItemText(hDlg, IDC_EDITRES_VALUE, szSetting, MAX_VAL_LEN);
if (UnFormatResString(szSetting, &ulVal, &ulEnd, lprei->ridResType)) {
ulLen = ulEnd - ulVal + 1;
//
// Validate the Current Settings
//
ResIndex = LocateValues(lprei->pData, lprei->ridResType,
ulVal, ulLen, ulEnd);
if (ResIndex == 0xFFFFFFFF ||
!ValidateAlignment(lprei->pData, lprei->ridResType,
ulVal, ResIndex)) {
//
// The setting is invalid, get the next valid setting
// BUGBUG - for now I'm just picking the "first", not the "next"!
//
GetRangeValues(lprei->pData, lprei->ridResType, 0,
&ulValidVal, &ulValidLen, &ulValidEnd, &ulFlags);
LoadString(MyDllModuleHandle, IDS_EDITRES_ENTRYERROR, szTitle, MAX_PATH);
LoadString(MyDllModuleHandle, IDS_EDITRES_VALIDATEERROR1, szTemp, MAX_MSG_LEN);
LoadString(MyDllModuleHandle, IDS_EDITRES_VALIDATEERROR2, szTemp1, MAX_MSG_LEN);
lstrcat(szTemp, szTemp1);
LoadString(MyDllModuleHandle, IDS_EDITRES_VALIDATEERROR3, szTemp1, MAX_MSG_LEN);
lstrcat(szTemp, szTemp1);
FormatResString(szSetting, ulVal, ulLen, lprei->ridResType);
FormatResString(szNewSetting, ulValidVal, ulValidLen, lprei->ridResType);
wsprintf(szMessage, szTemp, szSetting, szNewSetting);
if (MessageBox(hDlg, szMessage, szTitle,
MB_YESNO | MB_TASKMODAL | MB_ICONEXCLAMATION) == IDYES) {
//
// Update the Edited values.
//
*pulVal = ulValidVal;
*pulLen = ulValidLen;
*pulEnd = ulValidEnd;
bRet = TRUE;
} else {
bRet = FALSE;
}
} else {
//
// The specified values are valid
//
*pulVal = ulVal;
*pulLen = ulLen;
*pulEnd = ulEnd;
bRet = TRUE;
}
} else {
switch (lprei->ridResType) {
case ResType_Mem:
LoadString(MyDllModuleHandle, IDS_ERROR_BADMEMTEXT, szMessage, MAX_MSG_LEN);
break;
case ResType_IO:
LoadString(MyDllModuleHandle, IDS_ERROR_BADIOTEXT, szMessage, MAX_MSG_LEN);
break;
case ResType_DMA:
LoadString(MyDllModuleHandle, IDS_ERROR_BADDMATEXT, szMessage, MAX_MSG_LEN);
break;
case ResType_IRQ:
LoadString(MyDllModuleHandle, IDS_ERROR_BADIRQTEXT, szMessage, MAX_MSG_LEN);
break;
}
LoadString(MyDllModuleHandle, IDS_EDITRES_ENTRYERROR, szTitle, MAX_PATH);
MessageBox(hDlg, szMessage, szTitle, MB_OK | MB_TASKMODAL | MB_ICONASTERISK);
bRet = FALSE;
}
return bRet;
} // bValidateResoureceVal
BOOL
bConflictWarn(
HWND hDlg,
ULONG ulVal,
ULONG ulLen,
ULONG ulEnd,
PRESOURCEEDITINFO lprei
)
{
BOOL bRet = TRUE;
TCHAR szMessage[MAX_MSG_LEN], szTitle[MAX_PATH];
if (!(lprei->dwFlags & REI_FLAG_NONUSEREDIT)) {
//
// Non-user edits have been made so the conflict flag may not be
// up-to-date, check conflicts now.
//
UpdateEditResConflictList(hDlg, lprei, ulVal, ulLen, lprei->ulCurrentFlags);
}
if (lprei->dwFlags & REI_FLAGS_CONFLICT) {
LoadString(MyDllModuleHandle, IDS_EDITRES_CONFLICTWARNMSG, szMessage, MAX_MSG_LEN);
LoadString(MyDllModuleHandle, IDS_EDITRES_CONFLICTWARNTITLE, szTitle, MAX_PATH);
if (MessageBox(hDlg, szMessage, szTitle,
MB_YESNO | MB_DEFBUTTON2| MB_TASKMODAL | MB_ICONEXCLAMATION) == IDNO) {
bRet = FALSE;
} else {
bRet = TRUE; // User approved conflict
}
}
return bRet;
} // bConflictWarn
BOOL
ValidateAlignment(
IN LPBYTE pData,
IN RESOURCEID ResType,
IN ULONG ulValue,
IN ULONG ulResIndex
)
{
//
// I assume that the values specified fall within the min/max
// for the specified range (specified by pData and ulResIndex).
// Just validate the alignment if any.
//
switch (ResType) {
case ResType_Mem: {
PMEM_RESOURCE pMemData = (PMEM_RESOURCE)pData;
ULONG NtAlign = ~(DWORD)pMemData->MEM_Data[ulResIndex].MR_Align + 1;
div_t DivInfo;
if (NtAlign == 0 ||
NtAlign > pMemData->MEM_Data[ulResIndex].MR_Max) {
//
// bogus alignment, assume it's aligned
//
return TRUE;
}
DivInfo = div(ulValue, NtAlign);
return (DivInfo.rem == 0);
//return ((ulValue & (DWORD)pMemData->MEM_Data[ulResIndex].MR_Align) == ulValue);
}
case ResType_IO: {
PIO_RESOURCE pIoData = (PIO_RESOURCE)pData;
ULONG NtAlign = ~(DWORD)pIoData->IO_Data[ulResIndex].IOR_Align + 1;
div_t DivInfo;
if (NtAlign == 0 ||
NtAlign > pIoData->IO_Data[ulResIndex].IOR_Max) {
//
// bogus alignment, assume it's aligned
//
return TRUE;
}
DivInfo = div(ulValue, NtAlign);
return (DivInfo.rem == 0);
//return ((ulValue & (DWORD)pIoData->IO_Data[ulResIndex].IOR_Align) == ulValue);
}
case ResType_DMA:
return TRUE; // no alignment constraints
case ResType_IRQ:
return TRUE; // no alignment constraints
}
} // ValidateAlignment
BOOL
MakeResourceData(
OUT LPBYTE *ppResourceData,
OUT PULONG pulSize,
IN RESOURCEID ResType,
IN ULONG ulValue,
IN ULONG ulLen,
IN ULONG ulFlags
)
{
BOOL bStatus = TRUE;
try {
switch (ResType) {
case ResType_Mem: {
PMEM_RESOURCE p;
*pulSize = sizeof(MEM_RESOURCE);
*ppResourceData = malloc(*pulSize);
p = (PMEM_RESOURCE)(*ppResourceData);
p->MEM_Header.MD_Count = 0;
p->MEM_Header.MD_Type = MType_Range;
p->MEM_Header.MD_Alloc_Base = ulValue;
p->MEM_Header.MD_Alloc_End = ulValue + ulLen - 1;
p->MEM_Header.MD_Flags = ulFlags;
p->MEM_Header.MD_Reserved = 0;
break;
}
case ResType_IO: {
PIO_RESOURCE p;
*pulSize = sizeof(IO_RESOURCE);
*ppResourceData = malloc(*pulSize);
p = (PIO_RESOURCE)(*ppResourceData);
p->IO_Header.IOD_Count = 0;
p->IO_Header.IOD_Type = IOType_Range;
p->IO_Header.IOD_Alloc_Base = ulValue;
p->IO_Header.IOD_Alloc_End = ulValue + ulLen - 1;
p->IO_Header.IOD_DesFlags = ulFlags;
break;
}
case ResType_DMA: {
PDMA_RESOURCE p;
*pulSize = sizeof(DMA_RESOURCE);
*ppResourceData = malloc(*pulSize);
p = (PDMA_RESOURCE)(*ppResourceData);
p->DMA_Header.DD_Count = 0;
p->DMA_Header.DD_Type = DType_Range;
p->DMA_Header.DD_Flags = ulFlags;
p->DMA_Header.DD_Alloc_Chan = ulValue;
break;
}
case ResType_IRQ: {
PIRQ_RESOURCE p;
*pulSize = sizeof(IRQ_RESOURCE);
*ppResourceData = malloc(*pulSize);
p = (PIRQ_RESOURCE)(*ppResourceData);
p->IRQ_Header.IRQD_Count = 0;
p->IRQ_Header.IRQD_Type = IRQType_Range;
p->IRQ_Header.IRQD_Flags = ulFlags;
p->IRQ_Header.IRQD_Alloc_Num = ulValue;
p->IRQ_Header.IRQD_Affinity = 0xFFFFFFFF; //BUGBUG
break;
}
}
} except(EXCEPTION_EXECUTE_HANDLER) {
bStatus = FALSE;
}
return bStatus;
} // MakeResourceData