/*++ Copyright (c) 1995 Microsoft Corporation Module Name: devres1.c Abstract: Routines for displaying resource dialogs. Author: Paula Tomlinson (paulat) 7-Feb-1996 Revision History: Jamie Hunter (jamiehun) 19-Mar-1998 Removed EditResource Dialog Proceedures into this file Resource picking functionality improved --*/ #include "precomp.h" #pragma hdrstop #define Nearness(x,y) (((x)>(y))?(x)-(y):(y)-(x)) static UDACCEL udAccel[] = {{0,1},{1,16},{2,256},{3,4096},{4,16000}}; static const DWORD EditResHelpIDs[]= { IDC_EDITRES_INSTRUCTIONS, IDH_NOHELP, IDC_EDITRES_MFCHILDREN, IDH_NOHELP, IDC_EDITRES_VALUE_LABEL, IDH_DEVMGR_RESOURCES_EDIT_VALUE, IDC_EDITRES_VALUE, IDH_DEVMGR_RESOURCES_EDIT_VALUE, IDC_EDITRES_CONFLICTINFO, IDH_DEVMGR_RESOURCES_EDIT_INFO, IDC_EDITRES_CONFLICTTEXT, IDH_DEVMGR_RESOURCES_EDIT_INFO, IDC_EDITRES_CONFLICTLIST, IDH_DEVMGR_RESOURCES_EDIT_INFO, 0, 0 }; void InitEditResDlg( HWND hDlg, PRESOURCEEDITINFO lprei, ULONG64 ulVal, ULONG64 ulLen ); void ClearEditResConflictList( HWND hDlg, DWORD dwFlags ); void UpdateEditResConflictList( HWND hDlg, PRESOURCEEDITINFO lprei, ULONG64 ulVal, ULONG64 ulLen, ULONG ulFlags ); void GetOtherValues( IN LPBYTE pData, IN RESOURCEID ResType, IN LONG Increment, OUT PULONG64 pulValue, OUT PULONG64 pulLen, OUT PULONG64 pulEnd ); void UpdateEditResConflictList( HWND hDlg, PRESOURCEEDITINFO lprei, ULONG64 ulVal, ULONG64 ulLen, ULONG ulFlags ); BOOL bValidateResourceVal( HWND hDlg, PULONG64 pulVal, PULONG64 pulLen, PULONG64 pulEnd, PULONG pulIndex, PRESOURCEEDITINFO lprei ); BOOL bConflictWarn( HWND hDlg, ULONG64 ulVal, ULONG64 ulLen, ULONG64 ulEnd, PRESOURCEEDITINFO lprei ); void ClearEditResConflictList( HWND hDlg, DWORD dwFlags ); void UpdateMFChildList( HWND hDlg, PRESOURCEEDITINFO lprei ); //--------------------------------------------------------------------------- // Edit Resource Dialog Box //--------------------------------------------------------------------------- INT_PTR WINAPI EditResourceDlgProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam ) { TCHAR szBuffer[MAX_PATH]; // // ISSUE-2000/02/03-JamieHun Remove statics from EditResourceDlgProc // static ULONG64 ulEditedValue, ulEditedLen, ulEditedEnd; switch (wMsg) { case WM_INITDIALOG: { PRESOURCEEDITINFO lprei = (PRESOURCEEDITINFO)lParam; ULONG ulSize = 0; SetWindowLongPtr(hDlg, DWLP_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); SetFocus(GetDlgItem(hDlg, IDC_EDITRES_VALUE)); break; // return default (FALSE) to indicate we've set focus } case WM_NOTIFY: { PRESOURCEEDITINFO lprei = (PRESOURCEEDITINFO)GetWindowLongPtr(hDlg, DWLP_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, &ulEditedValue, &ulEditedLen, &ulEditedEnd); } else { GetOtherValues(lprei->pData, lprei->ridResType, -1, &ulEditedValue, &ulEditedLen, &ulEditedEnd); } pFormatResString(NULL,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) GetWindowLongPtr(hDlg, DWLP_USER); ULONG ulIndex; // // Validate the values (could have been manually edited) // if (bValidateResourceVal(hDlg, &ulEditedValue, &ulEditedLen, &ulEditedEnd, &ulIndex, 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. // //No HMACHINE if(bConflictWarn(hDlg, ulEditedValue, ulEditedLen, ulEditedEnd, lprei)) { lprei->ulCurrentVal = ulEditedValue; lprei->ulCurrentLen = ulEditedLen; lprei->ulCurrentEnd = ulEditedEnd; lprei->ulRangeCount = ulIndex; EndDialog(hDlg, IDOK); if (lprei->pData) { MyFree(lprei->pData); } } else { // // Format and display the data // pFormatResString(NULL,szBuffer, ulEditedValue, ulEditedLen, lprei->ridResType); SetDlgItemText(hDlg, IDC_EDITRES_VALUE, szBuffer); // // Update the Conflict List. // UpdateEditResConflictList(hDlg, lprei, ulEditedValue, ulEditedLen, lprei->ulCurrentFlags); } } return TRUE; } case IDCANCEL: { PRESOURCEEDITINFO lprei = (PRESOURCEEDITINFO)GetWindowLongPtr(hDlg, DWLP_USER); if (lprei->pData) { MyFree(lprei->pData); } EndDialog(hDlg, FALSE); return TRUE; } case IDC_EDITRES_VALUE: { switch (HIWORD(wParam)) { case EN_CHANGE: { PRESOURCEEDITINFO lprei = (PRESOURCEEDITINFO)GetWindowLongPtr(hDlg, DWLP_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; } case WM_HELP: // F1 WinHelp(((LPHELPINFO)lParam)->hItemHandle, DEVRES_HELP, HELP_WM_HELP, (ULONG_PTR)EditResHelpIDs); break; case WM_CONTEXTMENU: // right mouse click WinHelp((HWND)wParam, DEVRES_HELP, HELP_CONTEXTMENU, (ULONG_PTR)EditResHelpIDs); break; } return FALSE; } // EditResourceDlgProc void InitEditResDlg( HWND hDlg, PRESOURCEEDITINFO lprei, ULONG64 ulVal, ULONG64 ulLen ) { TCHAR szBuffer[MAX_PATH], szInstr[MAX_PATH], szTemp[MAX_PATH], szResType[MAX_PATH], szResTypeLC[MAX_PATH]; ULONG ulSize = 0; // // Set the initial Value // pFormatResString(NULL,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, (LPARAM)(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_Ex(&ulSize, lprei->ResDes, CM_RESDES_WIDTH_64,lprei->hMachine) == CR_SUCCESS) { lprei->pData = MyMalloc(ulSize); if (lprei->pData != NULL) { CM_Get_Res_Des_Data_Ex(lprei->ResDes, lprei->pData, ulSize, CM_RESDES_WIDTH_64,lprei->hMachine); } } // // Update the Conflict List. // UpdateEditResConflictList(hDlg, lprei, ulVal, ulLen, lprei->ulCurrentFlags); } // InitEditResDlg BOOL LocateClosestValue( IN LPBYTE pData, IN RESOURCEID ResType, IN ULONG64 TestValue, IN ULONG64 TestLen, IN INT Mode, OUT PULONG64 OutValue, OPTIONAL OUT PULONG64 OutLen, OPTIONAL OUT PULONG OutIndex OPTIONAL ) /*++ Routine Description: This routine finds the nearest valid address/range to that the user specified if Mode == 0, the nearest value is used if Mode > 0, the nearest higher value is used if Mode < 0, the nearest lower value is used Arguments: pData - information about the resources being selected ResType - type of resource being selected CurrentValue - value entered by user CurrentLen - length based on range entered by user Mode - search mode, -1 = previous, 1 = next, 0 = nearest OutValue - nearest valid value OutLen - length associated with nearest valid value Return Value: If exact match found, return TRUE otherwise FALSE --*/ { PGENERIC_RESOURCE pGenRes = (PGENERIC_RESOURCE)pData; ULONG64 Start, Len, End, Align; ULONG Flags; ULONG64 BestVal; ULONG64 BestValL; ULONG64 BestValU; ULONG64 FoundVal = 0; ULONG64 FoundLen = 0; ULONG FoundIndex = 0; ULONG Index; BOOL FindNearest = TRUE; // indicates we should find nearest // // precedence (1) Value&Len match exactly // precedence (2) closest valid value // // // cover a catch-all case - start of the very first resource range // pGetRangeValues(pData, ResType, 0, &Start, &Len, &End, &Align, &Flags); // // we have at least 1 found value // FoundVal = Start; FoundLen = Len; // // Find a nearby valid range to the one supplied // // // check each range at a time // sometimes ranges may not be given in ascending order // eg, first range is a preferred, second range is alternative // for (Index = 0; Index < pGenRes->GENERIC_Header.GENERIC_Count; Index++) { // // get limits for this range // pGetRangeValues(pData, ResType, Index, &Start, &Len, &End, &Align, &Flags); // // first, try to find a value that is GOOD, that is <= TestValue // BestValL = TestValue; if (pAlignValues(&BestValL, Start, Len, End, Align, -1) == FALSE) { // // if it failed, use the lowest value in this range (ie Start) // BestValL = Start; } // // find an upper value that is aligned // if (BestValL == TestValue) { // // if match was exact, skip test // BestValU = TestValue; } else { // // search for upper limit // BestValU = TestValue; if (pAlignValues(&BestValU, Start, Len, End, Align, 1) == FALSE) { // // couldn't use it - find highest valid value // BestValU = End-Len+1; if (pAlignValues(&BestValU, Start, Len, End, Align, -1) == FALSE) { // // still no go // BestValU = BestValL; } } } // // now we have found our boundaries // may need to modify, depending on preferences // if (Mode<0) { // // if range is < TestVal, use highest, else lowest // if (BestValU <= TestValue) { BestVal = BestValU; } else { BestVal = BestValL; } } else if (Mode>0) { // // if range is > TestVal, use lowest, else highest // if (BestValL >= TestValue) { BestVal = BestValL; } else { BestVal = BestValU; } } else { // // use closest of the two values // if (Nearness(BestValL,TestValue)<= Nearness(BestValU,TestValue)) { BestVal = BestValL; } else { BestVal = BestValU; } } // // we know that BestVal is valid within the range // and is the choice for this range // // // handle the match cases // if (TestValue == BestVal && TestLen == Len) { // // exact match // if (OutValue != NULL) { *OutValue = BestVal; } if (OutLen != NULL) { *OutLen = Len; } if (OutIndex != NULL) { *OutIndex = Index; } return TRUE; } if (FindNearest && Mode != 0) { // // we are currently in "FindNearest" mode which means // we haven't found one in the direction we wanted // if (Mode < 0 && BestVal <= TestValue) { // // not looking for nearness now we've found one lower // FoundVal = BestVal; FoundLen = Len; FoundIndex = Index; FindNearest = FALSE; } else if (Mode > 0 && BestVal >= TestValue) { // // not looking for nearness now we've found one higher // FoundVal = BestVal; FoundLen = Len; FoundIndex = Index; FindNearest = FALSE; } } else if (FindNearest || (Mode < 0 && BestVal <= TestValue) || (Mode > 0 && BestVal >= TestValue)) { if (Nearness(BestVal,TestValue) < Nearness(FoundVal,TestValue)) { // // this address is nearer // FoundVal = BestVal; FoundLen = Len; FoundIndex = Index; } else if (Nearness(BestVal,TestValue) == Nearness(FoundVal,TestValue)) { // // this address guess is as near as nearest guess, pick the better length // // I can't see any place that this should happen // but theoretically it could happen // so this is a safety net more than anything else // if (Nearness(Len,TestLen) < Nearness(FoundLen,TestLen)) { // // this length is nearer // FoundVal = BestVal; FoundLen = Len; FoundIndex = Index; } else if (Nearness(Len,TestLen) == Nearness(FoundLen,TestLen)) { // // pick the bigger (safer) // if (Len > FoundLen) { // // this length is bigger // FoundVal = BestVal; FoundLen = Len; FoundIndex = Index; } } } } } // // if we get here, we didn't find an exact match // // Use our best guess if (OutValue != NULL) { *OutValue = FoundVal; } if (OutLen != NULL) { *OutLen = FoundLen; } if (OutIndex != NULL) { *OutIndex = FoundIndex; } return FALSE; } void GetOtherValues( IN LPBYTE pData, IN RESOURCEID ResType, IN LONG Increment, IN OUT PULONG64 pulValue, IN OUT PULONG64 pulLen, IN OUT PULONG64 pulEnd ) /*++ Routine Description: Finds the next valid value, wrapping around to beginning/end value when end of range Arguments: pData - resource data ResType - resource type Increment - 1 or -1 pulValue - pointer to old/new start that is changed pulLen - pointer to old/new length pulEnd - pointer to old/new end Return Value: none --*/ { ULONG64 TestValue = *pulValue; ULONG64 TestLen = *pulLen; ULONG64 RetValue = 0; ULONG64 RetLen = 0; MYASSERT((Increment == 1) || (Increment == -1)); if (Increment == 1) { TestValue++; LocateClosestValue(pData,ResType,TestValue,TestLen, 1 ,&RetValue,&RetLen,NULL); if (RetValue < TestValue) { // // wrap around, find lowest possible valid address // LocateClosestValue(pData,ResType,0,TestLen, 0 ,&RetValue,&RetLen,NULL); } } else { TestValue--; LocateClosestValue(pData,ResType,TestValue,TestLen, -1 ,&RetValue,&RetLen,NULL); if (RetValue > TestValue) { // // wrap around, find highest possible valid address // LocateClosestValue(pData,ResType,(ULONG64)(-1),TestLen, 0 ,&RetValue,&RetLen,NULL); } } *pulValue = RetValue; *pulLen = RetLen; *pulEnd = RetValue + RetLen - 1; return; } // GetOtherValues void UpdateEditResConflictList( HWND hDlg, PRESOURCEEDITINFO lprei, ULONG64 ulVal, ULONG64 ulLen, ULONG ulFlags ) /*++ Routine Description: Updates all the conflict information for the selected resource Should give more details than UpdateDevResConflictList Arguments: hDlg - handle of this dialog to display into lprei - resource edit info ulVal - value to try ulLen - length to test ulFlags - flags part of resdes Return Value: none --*/ { CONFIGRET Status = CR_SUCCESS; HWND hwndConflictList = GetDlgItem(hDlg, IDC_EDITRES_CONFLICTLIST); ULONG ConflictCount = 0; ULONG ConflictIndex = 0; ULONG ulSize = 0; LPBYTE pResourceData = NULL; CONFLICT_LIST ConflictList = 0; PDEVICE_INFO_SET pDeviceInfoSet; CONFLICT_DETAILS ConflictDetails; TCHAR szBuffer[MAX_PATH]; TCHAR szItemFormat[MAX_PATH]; BOOL ReservedResource = FALSE; BOOL BadResource = FALSE; // // need resource-data for determining conflict // if (MakeResourceData(&pResourceData, &ulSize, lprei->ridResType, ulVal, ulLen, ulFlags)) { Status = CM_Query_Resource_Conflict_List(&ConflictList, lprei->lpdi->DevInst, lprei->ridResType, pResourceData, ulSize, DEVRES_WIDTH_FLAGS, lprei->hMachine); if (Status != CR_SUCCESS) { // // error occurred // ConflictList = 0; ConflictCount = 0; BadResource = TRUE; } else { // // find out how many things conflicted // Status = CM_Get_Resource_Conflict_Count(ConflictList,&ConflictCount); if (Status != CR_SUCCESS) { // // error shouldn't occur // MYASSERT(Status == CR_SUCCESS); ConflictCount = 0; BadResource = TRUE; } } } else { MYASSERT(FALSE); // // should not fail // ConflictList = 0; ConflictCount = 0; BadResource = TRUE; } if (BadResource) { // // The resource conflict information is indeterminate // SendMessage(hwndConflictList, LB_RESETCONTENT, 0, 0L); lprei->dwFlags &= ~REI_FLAGS_CONFLICT; 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 (ConflictCount || ReservedResource) { TreatAsReserved: SendMessage(hwndConflictList, LB_RESETCONTENT, 0, 0L); lprei->dwFlags |= REI_FLAGS_CONFLICT; if(ReservedResource == FALSE) { // // The resource conflicts with another unknown device. // LoadString(MyDllModuleHandle, IDS_EDITRES_DEVCONFLICT, szBuffer, MAX_PATH); SetDlgItemText(hDlg, IDC_EDITRES_CONFLICTTEXT, szBuffer); for(ConflictIndex = 0; ConflictIndex < ConflictCount ; ConflictIndex++) { // // obtain details for this conflict // ZeroMemory(&ConflictDetails,sizeof(ConflictDetails)); ConflictDetails.CD_ulSize = sizeof(ConflictDetails); ConflictDetails.CD_ulMask = CM_CDMASK_DEVINST | CM_CDMASK_DESCRIPTION | CM_CDMASK_FLAGS; Status = CM_Get_Resource_Conflict_Details(ConflictList,ConflictIndex,&ConflictDetails); if (Status == CR_SUCCESS) { if ((ConflictDetails.CD_ulFlags & CM_CDFLAGS_RESERVED) != 0) { // // treat as reserved - backtrack // ReservedResource = TRUE; goto TreatAsReserved; } // // convert CD_dnDevInst to string information // lstrcpy(szBuffer,ConflictDetails.CD_szDescription); if (szBuffer[0] == 0) { ReservedResource = TRUE; goto TreatAsReserved; } } else { MYASSERT(Status == CR_SUCCESS); ReservedResource = TRUE; goto TreatAsReserved; } SendMessage(hwndConflictList, LB_ADDSTRING, 0, (LPARAM)(LPSTR)szBuffer); } } else { LoadString(MyDllModuleHandle, IDS_EDITRES_RESERVED, szBuffer, MAX_PATH); SetDlgItemText(hDlg, IDC_EDITRES_CONFLICTTEXT, szBuffer); LoadString(MyDllModuleHandle, IDS_EDITRES_RESERVEDRANGE, szBuffer, MAX_PATH); SendMessage(hwndConflictList, LB_ADDSTRING, 0, (LPARAM)(LPSTR)szBuffer); } } else { // // The resource does not conflict with any other devices. // SendMessage(hwndConflictList, LB_RESETCONTENT, 0, 0L); 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); } if (ConflictList) { CM_Free_Resource_Conflict_Handle(ConflictList); } if (pResourceData != NULL) { MyFree(pResourceData); } return; } BOOL bValidateResourceVal( HWND hDlg, PULONG64 pulVal, PULONG64 pulLen, PULONG64 pulEnd, PULONG pulIndex, 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]; ULONG64 ulVal, ulEnd, ulLen; ULONG64 ulValidVal, ulValidLen; ULONG ulIndex; BOOL bRet; BOOL exact = TRUE; GetDlgItemText(hDlg, IDC_EDITRES_VALUE, szSetting, MAX_VAL_LEN); if (pUnFormatResString(szSetting, &ulVal, &ulEnd, lprei->ridResType)) { ulLen = ulEnd - ulVal + 1; // // Validate the Current Settings // // If an exact match doesn't exist // use a close match // close is based on start address // if (LocateClosestValue(lprei->pData, lprei->ridResType, ulVal, ulLen,0, &ulValidVal, &ulValidLen,&ulIndex) == FALSE) { // // An alternate setting was found // we think this might be what the user wanted // 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); pFormatResString(NULL, szSetting, ulVal, ulLen, lprei->ridResType); pFormatResString(NULL,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 = ulValidVal + ulValidLen - 1; *pulIndex = ulIndex; bRet = TRUE; } else { bRet = FALSE; } } else { // // The specified values are valid // *pulVal = ulVal; *pulLen = ulLen; *pulEnd = ulEnd; *pulIndex = ulIndex; 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, ULONG64 ulVal, ULONG64 ulLen, ULONG64 ulEnd, PRESOURCEEDITINFO lprei ) { BOOL bRet = TRUE; TCHAR szMessage[MAX_MSG_LEN], szTitle[MAX_PATH]; if (!(lprei->dwFlags & REI_FLAG_NONUSEREDIT)) { // // 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 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); // // 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 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