1 /* 2 * PROJECT: ReactOS system libraries 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Network property page provider 5 * COPYRIGHT: Copyright 2018 Eric Kohl (eric.kohl@reactos.org) 6 */ 7 8 #include "precomp.h" 9 10 typedef enum _PARAM_TYPE 11 { 12 NO_TYPE, 13 INT_TYPE, 14 LONG_TYPE, 15 WORD_TYPE, 16 DWORD_TYPE, 17 EDIT_TYPE, 18 ENUM_TYPE, 19 } PARAM_TYPE, *PPARAM_TYPE; 20 21 typedef struct _ENUM_OPTION 22 { 23 PWSTR pszValue; 24 PWSTR pszName; 25 } ENUM_OPTION, *PENUM_OPTION; 26 27 typedef struct _PARAMETER 28 { 29 PWSTR pszName; 30 PWSTR pszDescription; 31 PWSTR pszValue; 32 DWORD cchValueLength; 33 PWSTR pszDefault; 34 BOOL bOptional; 35 BOOL bPresent; 36 PARAM_TYPE Type; 37 38 DWORD dwEnumOptions; 39 PENUM_OPTION pEnumOptions; 40 41 BOOL bUpperCase; 42 INT iTextLimit; 43 44 INT iBase; 45 INT iStep; 46 LONG lMin; 47 LONG lMax; 48 } PARAMETER, *PPARAMETER; 49 50 typedef struct _PARAMETER_ARRAY 51 { 52 HDEVINFO DeviceInfoSet; 53 PSP_DEVINFO_DATA DeviceInfoData; 54 PPARAMETER pCurrentParam; 55 DWORD dwCount; 56 PARAMETER Array[0]; 57 } PARAMETER_ARRAY, *PPARAMETER_ARRAY; 58 59 60 static 61 VOID 62 FreeParameterArray( 63 _In_ PPARAMETER_ARRAY ParamArray) 64 { 65 INT i, j; 66 67 if (ParamArray == NULL) 68 return; 69 70 for (i = 0; i < ParamArray->dwCount; i++) 71 { 72 if (ParamArray->Array[i].pszName != NULL) 73 HeapFree(GetProcessHeap(), 0, ParamArray->Array[i].pszName); 74 75 if (ParamArray->Array[i].pszDescription != NULL) 76 HeapFree(GetProcessHeap(), 0, ParamArray->Array[i].pszDescription); 77 78 if (ParamArray->Array[i].pszDefault != NULL) 79 HeapFree(GetProcessHeap(), 0, ParamArray->Array[i].pszDefault); 80 81 82 if (ParamArray->Array[i].pEnumOptions != NULL) 83 { 84 for (j = 0; j < ParamArray->Array[i].dwEnumOptions; j++) 85 { 86 if (ParamArray->Array[i].pEnumOptions[j].pszValue != NULL) 87 HeapFree(GetProcessHeap(), 0, ParamArray->Array[i].pEnumOptions[j].pszValue); 88 89 if (ParamArray->Array[i].pEnumOptions[j].pszName != NULL) 90 HeapFree(GetProcessHeap(), 0, ParamArray->Array[i].pEnumOptions[j].pszName); 91 } 92 93 HeapFree(GetProcessHeap(), 0, ParamArray->Array[i].pEnumOptions); 94 } 95 } 96 97 HeapFree(GetProcessHeap(), 0, ParamArray); 98 } 99 100 101 static DWORD 102 GetStringValue( 103 _In_ HKEY hKey, 104 _In_ PWSTR pValueName, 105 _Out_ PWSTR *pString, 106 _Out_opt_ PDWORD pdwStringLength) 107 { 108 PWSTR pBuffer; 109 DWORD dwLength = 0; 110 DWORD dwRegType; 111 DWORD dwError; 112 113 *pString = NULL; 114 115 RegQueryValueExW(hKey, pValueName, NULL, &dwRegType, NULL, &dwLength); 116 117 if (dwLength == 0 || dwRegType != REG_SZ) 118 return ERROR_FILE_NOT_FOUND; 119 120 pBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength + sizeof(WCHAR)); 121 if (pBuffer == NULL) 122 return ERROR_NOT_ENOUGH_MEMORY; 123 124 dwError = RegQueryValueExW(hKey, pValueName, NULL, NULL, (LPBYTE)pBuffer, &dwLength); 125 if (dwError != ERROR_SUCCESS) 126 { 127 HeapFree(GetProcessHeap(), 0, pBuffer); 128 return dwError; 129 } 130 131 pBuffer[dwLength / sizeof(WCHAR)] = UNICODE_NULL; 132 133 *pString = pBuffer; 134 if (pdwStringLength) 135 *pdwStringLength = dwLength; 136 137 return ERROR_SUCCESS; 138 } 139 140 141 static DWORD 142 GetBooleanValue( 143 _In_ HKEY hKey, 144 _In_ PWSTR pValueName, 145 _In_ BOOL bDefault, 146 _Out_ PBOOL pValue) 147 { 148 WCHAR szBuffer[16]; 149 DWORD dwLength = 0; 150 DWORD dwRegType; 151 152 *pValue = bDefault; 153 154 dwLength = sizeof(szBuffer); 155 RegQueryValueExW(hKey, 156 pValueName, 157 NULL, 158 &dwRegType, 159 (LPBYTE)szBuffer, 160 &dwLength); 161 162 if (dwRegType == REG_SZ && dwLength >= sizeof(WCHAR)) 163 { 164 if (szBuffer[0] == L'0') 165 *pValue = FALSE; 166 else 167 *pValue = TRUE; 168 } 169 170 return ERROR_SUCCESS; 171 } 172 173 174 static DWORD 175 GetIntValue( 176 _In_ HKEY hKey, 177 _In_ PWSTR pValueName, 178 _In_ INT iDefault, 179 _Out_ PINT pValue) 180 { 181 WCHAR szBuffer[24]; 182 DWORD dwLength = 0; 183 DWORD dwRegType; 184 185 *pValue = iDefault; 186 187 dwLength = sizeof(szBuffer); 188 RegQueryValueExW(hKey, 189 pValueName, 190 NULL, 191 &dwRegType, 192 (LPBYTE)szBuffer, 193 &dwLength); 194 195 if (dwRegType == REG_SZ && dwLength >= sizeof(WCHAR)) 196 { 197 *pValue = _wtoi(szBuffer); 198 } 199 200 return ERROR_SUCCESS; 201 } 202 203 204 static DWORD 205 GetLongValue( 206 _In_ HKEY hKey, 207 _In_ PWSTR pValueName, 208 _In_ LONG lDefault, 209 _Out_ PLONG pValue) 210 { 211 WCHAR szBuffer[24]; 212 DWORD dwLength = 0; 213 DWORD dwRegType; 214 PWSTR ptr = NULL; 215 216 dwLength = sizeof(szBuffer); 217 RegQueryValueExW(hKey, 218 pValueName, 219 NULL, 220 &dwRegType, 221 (LPBYTE)szBuffer, 222 &dwLength); 223 224 if (dwRegType == REG_SZ && dwLength >= sizeof(WCHAR)) 225 { 226 *pValue = wcstol(szBuffer, &ptr, 10); 227 if (*pValue == 0 && ptr != NULL) 228 *pValue = lDefault; 229 } 230 else 231 { 232 *pValue = lDefault; 233 } 234 235 return ERROR_SUCCESS; 236 } 237 238 239 static 240 DWORD 241 GetEnumOptions( 242 _In_ HKEY hKey, 243 _In_ PPARAMETER pParameter) 244 { 245 HKEY hEnumKey = NULL; 246 PENUM_OPTION pOptions = NULL; 247 DWORD dwValues, dwMaxValueNameLen, dwMaxValueLen; 248 DWORD dwValueNameLength, dwValueLength; 249 DWORD i; 250 DWORD dwError; 251 252 dwError = RegOpenKeyExW(hKey, 253 L"enum", 254 0, 255 KEY_READ, 256 &hEnumKey); 257 if (dwError != ERROR_SUCCESS) 258 return dwError; 259 260 dwError = RegQueryInfoKeyW(hEnumKey, 261 NULL, 262 NULL, 263 NULL, 264 NULL, 265 NULL, 266 NULL, 267 &dwValues, 268 &dwMaxValueNameLen, 269 &dwMaxValueLen, 270 NULL, 271 NULL); 272 if (dwError != ERROR_SUCCESS) 273 { 274 ERR("RegQueryInfoKeyW failed (Error %lu)\n", dwError); 275 goto done; 276 } 277 278 pOptions = HeapAlloc(GetProcessHeap(), 279 HEAP_ZERO_MEMORY, 280 dwValues * sizeof(ENUM_OPTION)); 281 if (pOptions == NULL) 282 { 283 dwError = ERROR_OUTOFMEMORY; 284 goto done; 285 } 286 287 for (i = 0; i < dwValues; i++) 288 { 289 dwValueNameLength = dwMaxValueNameLen + sizeof(WCHAR); 290 pOptions[i].pszValue = HeapAlloc(GetProcessHeap(), 291 0, 292 dwValueNameLength * sizeof(WCHAR)); 293 if (pOptions[i].pszValue == NULL) 294 { 295 dwError = ERROR_OUTOFMEMORY; 296 goto done; 297 } 298 299 dwValueLength = dwMaxValueLen; 300 pOptions[i].pszName = HeapAlloc(GetProcessHeap(), 301 0, 302 dwValueLength); 303 if (pOptions[i].pszName == NULL) 304 { 305 dwError = ERROR_OUTOFMEMORY; 306 goto done; 307 } 308 309 dwError = RegEnumValueW(hEnumKey, 310 i, 311 pOptions[i].pszValue, 312 &dwValueNameLength, 313 NULL, 314 NULL, 315 (PBYTE)pOptions[i].pszName, 316 &dwValueLength); 317 if (dwError == ERROR_NO_MORE_ITEMS) 318 { 319 dwError == ERROR_SUCCESS; 320 goto done; 321 } 322 else if (dwError != ERROR_SUCCESS) 323 { 324 goto done; 325 } 326 } 327 328 pParameter->pEnumOptions = pOptions; 329 pParameter->dwEnumOptions = dwValues; 330 pOptions = NULL; 331 332 done: 333 if (pOptions != NULL) 334 { 335 for (i = 0; i < dwValues; i++) 336 { 337 if (pOptions[i].pszValue != NULL) 338 HeapFree(GetProcessHeap(), 0, pOptions[i].pszValue); 339 340 if (pOptions[i].pszName != NULL) 341 HeapFree(GetProcessHeap(), 0, pOptions[i].pszName); 342 } 343 344 HeapFree(GetProcessHeap(), 0, pOptions); 345 } 346 347 if (hEnumKey != NULL) 348 RegCloseKey(hEnumKey); 349 350 return dwError; 351 } 352 353 354 static 355 INT 356 FindEnumOption( 357 _In_ PPARAMETER pParameter, 358 _In_ PWSTR pszValue) 359 { 360 INT i; 361 362 if ((pParameter->pEnumOptions == NULL) || 363 (pParameter->dwEnumOptions == 0)) 364 return -1; 365 366 for (i = 0; i < pParameter->dwEnumOptions; i++) 367 { 368 if (_wcsicmp(pParameter->pEnumOptions[i].pszValue, pszValue) == 0) 369 return i; 370 } 371 372 return -1; 373 } 374 375 376 static 377 BOOL 378 BuildParameterArray( 379 _In_ HDEVINFO DeviceInfoSet, 380 _In_ PSP_DEVINFO_DATA DeviceInfoData, 381 _Out_ PPARAMETER_ARRAY *ParameterArray) 382 { 383 HKEY hDriverKey = INVALID_HANDLE_VALUE; 384 HKEY hParamsKey = INVALID_HANDLE_VALUE; 385 HKEY hParamKey; 386 PPARAMETER_ARRAY ParamArray = NULL; 387 DWORD dwSubKeys, dwMaxSubKeyLen, dwKeyLen, dwIndex; 388 PWSTR pszType = NULL; 389 LONG lError; 390 LONG lDefaultMin, lDefaultMax; 391 BOOL ret = FALSE; 392 393 hDriverKey = SetupDiOpenDevRegKey(DeviceInfoSet, 394 DeviceInfoData, 395 DICS_FLAG_GLOBAL, 396 0, 397 DIREG_DRV, 398 KEY_READ); 399 if (hDriverKey == INVALID_HANDLE_VALUE) 400 { 401 ERR("SetupDiOpenDevRegKey() failed\n"); 402 return FALSE; 403 } 404 405 lError = RegOpenKeyExW(hDriverKey, 406 L"Ndi\\Params", 407 0, 408 KEY_READ, 409 &hParamsKey); 410 if (lError != ERROR_SUCCESS) 411 { 412 ERR("RegOpenKeyExW failed (Error %lu)\n", lError); 413 goto done; 414 } 415 416 lError = RegQueryInfoKeyW(hParamsKey, 417 NULL, 418 NULL, 419 NULL, 420 &dwSubKeys, 421 &dwMaxSubKeyLen, 422 NULL, 423 NULL, 424 NULL, 425 NULL, 426 NULL, 427 NULL); 428 if (lError != ERROR_SUCCESS) 429 { 430 ERR("RegOpenKeyExW failed (Error %lu)\n", lError); 431 goto done; 432 } 433 434 TRACE("Sub keys: %lu\n", dwSubKeys); 435 436 if (dwSubKeys == 0) 437 { 438 TRACE("No sub keys. Done!\n"); 439 goto done; 440 } 441 442 ParamArray = HeapAlloc(GetProcessHeap(), 443 HEAP_ZERO_MEMORY, 444 sizeof(PARAMETER_ARRAY) + (dwSubKeys * sizeof(PARAMETER))); 445 if (ParamArray == NULL) 446 { 447 ERR("Parameter array allocation failed!\n"); 448 goto done; 449 } 450 451 ParamArray->DeviceInfoSet = DeviceInfoSet; 452 ParamArray->DeviceInfoData = DeviceInfoData; 453 ParamArray->dwCount = dwSubKeys; 454 455 dwMaxSubKeyLen++; 456 457 for (dwIndex = 0; dwIndex < dwSubKeys; dwIndex++) 458 { 459 ParamArray->Array[dwIndex].pszName = HeapAlloc(GetProcessHeap(), 460 0, 461 dwMaxSubKeyLen * sizeof(WCHAR)); 462 if (ParamArray->Array[dwIndex].pszName == NULL) 463 { 464 ERR("Parameter array allocation failed!\n"); 465 goto done; 466 } 467 468 dwKeyLen = dwMaxSubKeyLen; 469 lError = RegEnumKeyExW(hParamsKey, 470 dwIndex, 471 ParamArray->Array[dwIndex].pszName, 472 &dwKeyLen, 473 NULL, 474 NULL, 475 NULL, 476 NULL); 477 if (lError != ERROR_SUCCESS) 478 break; 479 480 TRACE("Sub key '%S'\n", ParamArray->Array[dwIndex].pszName); 481 482 lError = RegOpenKeyExW(hParamsKey, 483 ParamArray->Array[dwIndex].pszName, 484 0, 485 KEY_READ, 486 &hParamKey); 487 if (lError == ERROR_SUCCESS) 488 { 489 GetStringValue(hParamKey, 490 L"ParamDesc", 491 &ParamArray->Array[dwIndex].pszDescription, 492 NULL); 493 494 GetStringValue(hParamKey, 495 L"Type", 496 &pszType, 497 NULL); 498 if (pszType != NULL) 499 { 500 if (_wcsicmp(pszType, L"int") == 0) 501 ParamArray->Array[dwIndex].Type = INT_TYPE; 502 else if (_wcsicmp(pszType, L"long") == 0) 503 ParamArray->Array[dwIndex].Type = LONG_TYPE; 504 else if (_wcsicmp(pszType, L"word") == 0) 505 ParamArray->Array[dwIndex].Type = WORD_TYPE; 506 else if (_wcsicmp(pszType, L"dword") == 0) 507 ParamArray->Array[dwIndex].Type = DWORD_TYPE; 508 else if (_wcsicmp(pszType, L"edit") == 0) 509 ParamArray->Array[dwIndex].Type = EDIT_TYPE; 510 else if (_wcsicmp(pszType, L"enum") == 0) 511 ParamArray->Array[dwIndex].Type = ENUM_TYPE; 512 else 513 ParamArray->Array[dwIndex].Type = NO_TYPE; 514 515 HeapFree(GetProcessHeap(), 0, pszType); 516 pszType = NULL; 517 } 518 519 GetStringValue(hParamKey, 520 L"Default", 521 &ParamArray->Array[dwIndex].pszDefault, 522 NULL); 523 524 GetBooleanValue(hParamKey, 525 L"Optional", 526 FALSE, 527 &ParamArray->Array[dwIndex].bOptional); 528 529 if (ParamArray->Array[dwIndex].Type == INT_TYPE || 530 ParamArray->Array[dwIndex].Type == LONG_TYPE || 531 ParamArray->Array[dwIndex].Type == WORD_TYPE || 532 ParamArray->Array[dwIndex].Type == DWORD_TYPE) 533 { 534 if (ParamArray->Array[dwIndex].Type == INT_TYPE) 535 { 536 lDefaultMin = -32768L; //MIN_SHORT; 537 lDefaultMax = 32767L; //MAX_SHORT; 538 } 539 else if (ParamArray->Array[dwIndex].Type == LONG_TYPE) 540 { 541 lDefaultMin = (-2147483647L - 1); // MIN_LONG; 542 lDefaultMax = 2147483647L; // MAX_LONG; 543 } 544 else if (ParamArray->Array[dwIndex].Type == WORD_TYPE) 545 { 546 lDefaultMin = 0L; 547 lDefaultMax = 65535L; // MAX_WORD; 548 } 549 #if 0 550 else if (ParamArray->Array[dwIndex].Type == DWORD_TYPE) 551 { 552 lDefaultMin = 0; 553 lDefaultMax = 4294967295; //MAX_DWORD; 554 } 555 #endif 556 557 GetLongValue(hParamKey, 558 L"Min", 559 lDefaultMin, 560 &ParamArray->Array[dwIndex].lMin); 561 562 GetLongValue(hParamKey, 563 L"Max", 564 lDefaultMax, 565 &ParamArray->Array[dwIndex].lMax); 566 567 GetIntValue(hParamKey, 568 L"Base", 569 10, 570 &ParamArray->Array[dwIndex].iBase); 571 572 GetIntValue(hParamKey, 573 L"Step", 574 1, 575 &ParamArray->Array[dwIndex].iStep); 576 } 577 else if (ParamArray->Array[dwIndex].Type == EDIT_TYPE) 578 { 579 GetBooleanValue(hParamKey, 580 L"UpperCase", 581 FALSE, 582 &ParamArray->Array[dwIndex].bUpperCase); 583 584 GetIntValue(hParamKey, 585 L"TextLimit", 586 0, 587 &ParamArray->Array[dwIndex].iTextLimit); 588 } 589 else if (ParamArray->Array[dwIndex].Type == ENUM_TYPE) 590 { 591 GetEnumOptions(hParamKey, 592 &ParamArray->Array[dwIndex]); 593 } 594 595 RegCloseKey(hParamKey); 596 } 597 598 lError = GetStringValue(hDriverKey, 599 ParamArray->Array[dwIndex].pszName, 600 &ParamArray->Array[dwIndex].pszValue, 601 &ParamArray->Array[dwIndex].cchValueLength); 602 if ((lError == ERROR_SUCCESS) || 603 (ParamArray->Array[dwIndex].pszDefault != NULL)) 604 { 605 ParamArray->Array[dwIndex].bPresent = TRUE; 606 } 607 } 608 609 *ParameterArray = ParamArray; 610 ret = TRUE; 611 612 done: 613 if (ret == FALSE && ParamArray != NULL) 614 FreeParameterArray(ParamArray); 615 616 if (hParamsKey != INVALID_HANDLE_VALUE) 617 RegCloseKey(hParamsKey); 618 619 if (hDriverKey != INVALID_HANDLE_VALUE) 620 RegCloseKey(hDriverKey); 621 622 return ret; 623 } 624 625 626 static 627 VOID 628 ReadParameterValue( 629 HWND hwnd, 630 PPARAMETER pParam) 631 { 632 INT iIndex, iLength; 633 634 if (pParam->Type == ENUM_TYPE) 635 { 636 iIndex = ComboBox_GetCurSel(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_LIST)); 637 if (iIndex != CB_ERR && iIndex < pParam->dwEnumOptions) 638 { 639 iLength = wcslen(pParam->pEnumOptions[iIndex].pszValue); 640 if (iLength > pParam->cchValueLength) 641 { 642 if (pParam->pszValue != NULL) 643 HeapFree(GetProcessHeap(), 0, pParam->pszValue); 644 645 pParam->pszValue = HeapAlloc(GetProcessHeap(), 0, (iLength + 1) * sizeof(WCHAR)); 646 } 647 648 if (pParam->pszValue != NULL) 649 { 650 wcscpy(pParam->pszValue, 651 pParam->pEnumOptions[iIndex].pszValue); 652 pParam->cchValueLength = iLength; 653 } 654 } 655 } 656 else 657 { 658 iLength = Edit_GetTextLength(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT)); 659 if (iLength > pParam->cchValueLength) 660 { 661 if (pParam->pszValue != NULL) 662 HeapFree(GetProcessHeap(), 0, pParam->pszValue); 663 664 pParam->pszValue = HeapAlloc(GetProcessHeap(), 0, (iLength + 1) * sizeof(WCHAR)); 665 } 666 667 if (pParam->pszValue != NULL) 668 { 669 Edit_GetText(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), 670 pParam->pszValue, 671 iLength + 1); 672 pParam->cchValueLength = iLength; 673 } 674 } 675 } 676 677 678 static 679 VOID 680 WriteParameterArray( 681 _In_ HWND hwnd, 682 _In_ PPARAMETER_ARRAY ParamArray) 683 { 684 PPARAMETER Param; 685 HKEY hDriverKey; 686 INT i; 687 688 if (ParamArray == NULL) 689 return; 690 691 hDriverKey = SetupDiOpenDevRegKey(ParamArray->DeviceInfoSet, 692 ParamArray->DeviceInfoData, 693 DICS_FLAG_GLOBAL, 694 0, 695 DIREG_DRV, 696 KEY_WRITE); 697 if (hDriverKey == INVALID_HANDLE_VALUE) 698 { 699 ERR("SetupDiOpenDevRegKey() failed\n"); 700 return; 701 } 702 703 for (i = 0; i < ParamArray->dwCount; i++) 704 { 705 Param = &ParamArray->Array[i]; 706 707 if (Param == ParamArray->pCurrentParam) 708 { 709 ReadParameterValue(hwnd, Param); 710 } 711 712 if (Param->bPresent) 713 { 714 TRACE("Set '%S' --> '%S'\n", Param->pszName, Param->pszValue); 715 RegSetValueExW(hDriverKey, 716 Param->pszName, 717 0, 718 REG_SZ, 719 (LPBYTE)Param->pszValue, 720 (wcslen(Param->pszValue) + 1) * sizeof(WCHAR)); 721 } 722 else 723 { 724 TRACE("Delete '%S'\n", Param->pszName); 725 RegDeleteValueW(hDriverKey, 726 Param->pszName); 727 } 728 } 729 730 RegCloseKey(hDriverKey); 731 } 732 733 734 static 735 VOID 736 DisplayParameter( 737 _In_ HWND hwnd, 738 _In_ PPARAMETER Parameter) 739 { 740 HWND hwndControl; 741 LONG_PTR Style; 742 INT idx; 743 DWORD i; 744 745 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_PRESENT), (Parameter->bOptional) ? SW_SHOW : SW_HIDE); 746 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_NOT_PRESENT), (Parameter->bOptional) ? SW_SHOW : SW_HIDE); 747 if (Parameter->bOptional) 748 { 749 if (Parameter->bPresent) 750 Button_SetCheck(GetDlgItem(hwnd, IDC_PROPERTY_PRESENT), BST_CHECKED); 751 else 752 Button_SetCheck(GetDlgItem(hwnd, IDC_PROPERTY_NOT_PRESENT), BST_CHECKED); 753 } 754 755 switch (Parameter->Type) 756 { 757 case INT_TYPE: 758 case LONG_TYPE: 759 case WORD_TYPE: 760 case DWORD_TYPE: 761 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_LIST), SW_HIDE); 762 763 hwndControl = GetDlgItem(hwnd, IDC_PROPERTY_VALUE_UPDN); 764 765 if (Parameter->Type != DWORD_TYPE) 766 { 767 EnableWindow(hwndControl, Parameter->bPresent); 768 ShowWindow(hwndControl, SW_SHOW); 769 } 770 771 if (Parameter->Type == WORD_TYPE || Parameter->Type == DWORD_TYPE) 772 SendMessage(hwndControl, UDM_SETBASE, Parameter->iBase, 0); 773 else 774 SendMessage(hwndControl, UDM_SETBASE, 10, 0); 775 776 if (Parameter->Type != DWORD_TYPE) 777 { 778 TRACE("SetMin %ld SetMax %ld\n", Parameter->lMin, Parameter->lMax); 779 SendMessage(hwndControl, UDM_SETRANGE32, Parameter->lMin, Parameter->lMax); 780 } 781 782 hwndControl = GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT); 783 EnableWindow(hwndControl, Parameter->bPresent); 784 ShowWindow(hwndControl, SW_SHOW); 785 786 Style = GetWindowLongPtr(hwndControl, GWL_STYLE); 787 Style |= ES_NUMBER; 788 SetWindowLongPtr(hwndControl, GWL_STYLE, Style); 789 790 Edit_LimitText(hwndControl, 0); 791 792 if (Parameter->pszValue) 793 Edit_SetText(hwndControl, Parameter->pszValue); 794 else if (Parameter->pszDefault) 795 Edit_SetText(hwndControl, Parameter->pszDefault); 796 break; 797 798 case EDIT_TYPE: 799 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_UPDN), SW_HIDE); 800 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_LIST), SW_HIDE); 801 802 hwndControl = GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT); 803 EnableWindow(hwndControl, Parameter->bPresent); 804 ShowWindow(hwndControl, SW_SHOW); 805 806 Style = GetWindowLongPtr(hwndControl, GWL_STYLE); 807 Style &= ~ES_NUMBER; 808 if (Parameter->bUpperCase) 809 Style |= ES_UPPERCASE; 810 else 811 Style &= ~ES_UPPERCASE; 812 SetWindowLongPtr(hwndControl, GWL_STYLE, Style); 813 814 Edit_LimitText(hwndControl, Parameter->iTextLimit); 815 816 if (Parameter->pszValue) 817 Edit_SetText(hwndControl, Parameter->pszValue); 818 else if (Parameter->pszDefault) 819 Edit_SetText(hwndControl, Parameter->pszDefault); 820 break; 821 822 case ENUM_TYPE: 823 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), SW_HIDE); 824 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_UPDN), SW_HIDE); 825 826 hwndControl = GetDlgItem(hwnd, IDC_PROPERTY_VALUE_LIST); 827 EnableWindow(hwndControl, Parameter->bPresent); 828 ShowWindow(hwndControl, SW_SHOW); 829 830 ComboBox_ResetContent(hwndControl); 831 832 if (Parameter->pEnumOptions != NULL && Parameter->dwEnumOptions != 0) 833 { 834 for (i = 0; i < Parameter->dwEnumOptions; i++) 835 { 836 ComboBox_AddString(hwndControl, Parameter->pEnumOptions[i].pszName); 837 } 838 } 839 840 if (Parameter->pszValue) 841 { 842 idx = FindEnumOption(Parameter, Parameter->pszValue); 843 if (idx != CB_ERR) 844 ComboBox_SetCurSel(hwndControl, idx); 845 } 846 else if (Parameter->pszDefault) 847 { 848 idx = FindEnumOption(Parameter, Parameter->pszDefault); 849 if (idx != CB_ERR) 850 ComboBox_SetCurSel(hwndControl, idx); 851 } 852 break; 853 854 default: 855 break; 856 } 857 } 858 859 860 static 861 BOOL 862 OnInitDialog( 863 HWND hwnd, 864 WPARAM wParam, 865 LPARAM lParam) 866 { 867 PPARAMETER_ARRAY pParamArray; 868 HWND hwndControl; 869 PWSTR pszText; 870 DWORD i; 871 INT idx; 872 873 TRACE("OnInitDialog()\n"); 874 875 pParamArray = (PPARAMETER_ARRAY)((LPPROPSHEETPAGEW)lParam)->lParam; 876 if (pParamArray == NULL) 877 { 878 ERR("pParamArray is NULL\n"); 879 return FALSE; 880 } 881 882 SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)pParamArray); 883 884 hwndControl = GetDlgItem(hwnd, IDC_PROPERTY_NAME); 885 if (hwndControl) 886 { 887 for (i = 0; i < pParamArray->dwCount; i++) 888 { 889 if (pParamArray->Array[i].pszDescription != NULL) 890 pszText = pParamArray->Array[i].pszDescription; 891 else 892 pszText = pParamArray->Array[i].pszName; 893 894 idx = ListBox_AddString(hwndControl, pszText); 895 if (idx != LB_ERR) 896 ListBox_SetItemData(hwndControl, idx, (LPARAM)&pParamArray->Array[i]); 897 } 898 899 if (pParamArray->dwCount > 0) 900 { 901 ListBox_SetCurSel(hwndControl, 0); 902 pParamArray->pCurrentParam = (PPARAMETER)ListBox_GetItemData(hwndControl, 0); 903 DisplayParameter(hwnd, pParamArray->pCurrentParam); 904 } 905 } 906 907 return TRUE; 908 } 909 910 911 static 912 VOID 913 OnCommand( 914 HWND hwnd, 915 WPARAM wParam, 916 LPARAM lParam) 917 { 918 PPARAMETER_ARRAY pParamArray; 919 INT iIndex; 920 921 TRACE("OnCommand()\n"); 922 923 pParamArray = (PPARAMETER_ARRAY)GetWindowLongPtr(hwnd, DWLP_USER); 924 if (pParamArray == NULL) 925 { 926 ERR("pParamArray is NULL\n"); 927 return; 928 } 929 930 if ((LOWORD(wParam) == IDC_PROPERTY_NAME) && (HIWORD(wParam) == LBN_SELCHANGE)) 931 { 932 if (pParamArray->pCurrentParam != NULL) 933 { 934 ReadParameterValue(hwnd, pParamArray->pCurrentParam); 935 } 936 937 iIndex = ListBox_GetCurSel((HWND)lParam); 938 if (iIndex != LB_ERR && iIndex < pParamArray->dwCount) 939 { 940 pParamArray->pCurrentParam = (PPARAMETER)ListBox_GetItemData((HWND)lParam, iIndex); 941 DisplayParameter(hwnd, pParamArray->pCurrentParam); 942 } 943 } 944 else if ((LOWORD(wParam) == IDC_PROPERTY_PRESENT) && (HIWORD(wParam) == BN_CLICKED)) 945 { 946 EnableWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), TRUE); 947 EnableWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_UPDN), TRUE); 948 EnableWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_LIST), TRUE); 949 pParamArray->pCurrentParam->bPresent = TRUE; 950 } 951 else if ((LOWORD(wParam) == IDC_PROPERTY_NOT_PRESENT) && (HIWORD(wParam) == BN_CLICKED)) 952 { 953 EnableWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), FALSE); 954 EnableWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_UPDN), FALSE); 955 EnableWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_LIST), FALSE); 956 pParamArray->pCurrentParam->bPresent = FALSE; 957 } 958 } 959 960 961 static 962 VOID 963 OnNotify( 964 HWND hwnd, 965 WPARAM wParam, 966 LPARAM lParam) 967 { 968 PPARAMETER_ARRAY pParamArray; 969 970 TRACE("OnNotify()\n"); 971 972 pParamArray = (PPARAMETER_ARRAY)GetWindowLongPtr(hwnd, DWLP_USER); 973 if (pParamArray == NULL) 974 { 975 ERR("pParamArray is NULL\n"); 976 return; 977 } 978 979 if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY) 980 { 981 TRACE("PSN_APPLY!\n"); 982 WriteParameterArray(hwnd, pParamArray); 983 } 984 else if (((LPNMHDR)lParam)->code == (UINT)UDN_DELTAPOS) 985 { 986 LPNMUPDOWN pUpDown = (LPNMUPDOWN)lParam; 987 pUpDown->iDelta *= pParamArray->pCurrentParam->iStep; 988 } 989 } 990 991 992 static 993 VOID 994 OnDestroy( 995 HWND hwnd) 996 { 997 PPARAMETER_ARRAY pParamArray; 998 999 TRACE("OnDestroy()\n"); 1000 1001 pParamArray = (PPARAMETER_ARRAY)GetWindowLongPtr(hwnd, DWLP_USER); 1002 if (pParamArray == NULL) 1003 { 1004 ERR("pParamArray is NULL\n"); 1005 return; 1006 } 1007 1008 FreeParameterArray(pParamArray); 1009 SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)NULL); 1010 } 1011 1012 1013 static 1014 INT_PTR 1015 CALLBACK 1016 NetPropertyPageDlgProc( 1017 HWND hwnd, 1018 UINT uMsg, 1019 WPARAM wParam, 1020 LPARAM lParam) 1021 { 1022 switch (uMsg) 1023 { 1024 case WM_INITDIALOG: 1025 return OnInitDialog(hwnd, wParam, lParam); 1026 1027 case WM_COMMAND: 1028 OnCommand(hwnd, wParam, lParam); 1029 break; 1030 1031 case WM_NOTIFY: 1032 OnNotify(hwnd, wParam, lParam); 1033 break; 1034 1035 case WM_DESTROY: 1036 OnDestroy(hwnd); 1037 break; 1038 1039 default: 1040 break; 1041 } 1042 1043 return FALSE; 1044 } 1045 1046 1047 BOOL 1048 WINAPI 1049 NetPropPageProvider( 1050 PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest, 1051 LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc, 1052 LPARAM lParam) 1053 { 1054 PROPSHEETPAGEW PropSheetPage; 1055 HPROPSHEETPAGE hPropSheetPage; 1056 PPARAMETER_ARRAY ParameterArray = NULL; 1057 1058 TRACE("NetPropPageProvider(%p %p %lx)\n", 1059 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam); 1060 1061 if (!BuildParameterArray(lpPropSheetPageRequest->DeviceInfoSet, 1062 lpPropSheetPageRequest->DeviceInfoData, 1063 &ParameterArray)) 1064 return FALSE; 1065 1066 if (lpPropSheetPageRequest->PageRequested == SPPSR_ENUM_ADV_DEVICE_PROPERTIES) 1067 { 1068 TRACE("SPPSR_ENUM_ADV_DEVICE_PROPERTIES\n"); 1069 1070 PropSheetPage.dwSize = sizeof(PROPSHEETPAGEW); 1071 PropSheetPage.dwFlags = 0; 1072 PropSheetPage.hInstance = netcfgx_hInstance; 1073 PropSheetPage.u.pszTemplate = MAKEINTRESOURCE(IDD_NET_PROPERTY_DLG); 1074 PropSheetPage.pfnDlgProc = NetPropertyPageDlgProc; 1075 PropSheetPage.lParam = (LPARAM)ParameterArray; 1076 PropSheetPage.pfnCallback = NULL; 1077 1078 hPropSheetPage = CreatePropertySheetPageW(&PropSheetPage); 1079 if (hPropSheetPage == NULL) 1080 { 1081 ERR("CreatePropertySheetPageW() failed!\n"); 1082 return FALSE; 1083 } 1084 1085 if (!(*lpfnAddPropSheetPageProc)(hPropSheetPage, lParam)) 1086 { 1087 ERR("lpfnAddPropSheetPageProc() failed!\n"); 1088 DestroyPropertySheetPage(hPropSheetPage); 1089 return FALSE; 1090 } 1091 } 1092 1093 TRACE("Done!\n"); 1094 1095 return TRUE; 1096 } 1097 1098 /* EOF */ 1099