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