[NETCFGX] NetPropPageProvider: Handle the Min and Max values for INT, LONG and WORD...
[reactos.git] / dll / win32 / netcfgx / propertypage.c
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 */