[NETCFGX] Fix an assignment typo.
[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 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 */