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