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