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)
10 typedef enum _PARAM_TYPE
19 } PARAM_TYPE
, *PPARAM_TYPE
;
21 typedef struct _ENUM_OPTION
25 } ENUM_OPTION
, *PENUM_OPTION
;
27 typedef struct _PARAMETER
38 PENUM_OPTION pEnumOptions
;
43 } PARAMETER
, *PPARAMETER
;
45 typedef struct _PARAMETER_ARRAY
47 PPARAMETER pCurrentParam
;
50 } PARAMETER_ARRAY
, *PPARAMETER_ARRAY
;
56 _In_ PPARAMETER_ARRAY ParamArray
)
60 if (ParamArray
== NULL
)
63 for (i
= 0; i
< ParamArray
->dwCount
; i
++)
65 if (ParamArray
->Array
[i
].pszName
!= NULL
)
66 HeapFree(GetProcessHeap(), 0, ParamArray
->Array
[i
].pszName
);
68 if (ParamArray
->Array
[i
].pszDescription
!= NULL
)
69 HeapFree(GetProcessHeap(), 0, ParamArray
->Array
[i
].pszDescription
);
71 if (ParamArray
->Array
[i
].pszDefault
!= NULL
)
72 HeapFree(GetProcessHeap(), 0, ParamArray
->Array
[i
].pszDefault
);
75 if (ParamArray
->Array
[i
].pEnumOptions
!= NULL
)
77 for (j
= 0; j
< ParamArray
->Array
[i
].dwEnumOptions
; j
++)
79 if (ParamArray
->Array
[i
].pEnumOptions
[j
].pszValue
!= NULL
)
80 HeapFree(GetProcessHeap(), 0, ParamArray
->Array
[i
].pEnumOptions
[j
].pszValue
);
82 if (ParamArray
->Array
[i
].pEnumOptions
[j
].pszName
!= NULL
)
83 HeapFree(GetProcessHeap(), 0, ParamArray
->Array
[i
].pEnumOptions
[j
].pszName
);
86 HeapFree(GetProcessHeap(), 0, ParamArray
->Array
[i
].pEnumOptions
);
90 HeapFree(GetProcessHeap(), 0, ParamArray
);
107 RegQueryValueExW(hKey
, pValueName
, NULL
, &dwRegType
, NULL
, &dwLength
);
109 if (dwLength
== 0 || dwRegType
!= REG_SZ
)
110 return ERROR_FILE_NOT_FOUND
;
112 pBuffer
= HeapAlloc(GetProcessHeap(), 0, dwLength
+ sizeof(WCHAR
));
114 return ERROR_NOT_ENOUGH_MEMORY
;
116 dwError
= RegQueryValueExW(hKey
, pValueName
, NULL
, NULL
, (LPBYTE
)pBuffer
, &dwLength
);
117 if (dwError
!= ERROR_SUCCESS
)
119 HeapFree(GetProcessHeap(), 0, pBuffer
);
123 pBuffer
[dwLength
/ sizeof(WCHAR
)] = UNICODE_NULL
;
127 return ERROR_SUCCESS
;
134 _In_ PWSTR pValueName
,
144 dwLength
= sizeof(szBuffer
);
145 RegQueryValueExW(hKey
,
152 if (dwRegType
== REG_SZ
&& dwLength
>= sizeof(WCHAR
))
154 if (szBuffer
[0] == L
'0')
160 return ERROR_SUCCESS
;
167 _In_ PWSTR pValueName
,
177 dwLength
= sizeof(szBuffer
);
178 RegQueryValueExW(hKey
,
185 if (dwRegType
== REG_SZ
&& dwLength
>= sizeof(WCHAR
))
187 *pValue
= _wtoi(szBuffer
);
190 return ERROR_SUCCESS
;
198 _In_ PPARAMETER pParameter
)
200 HKEY hEnumKey
= NULL
;
201 PENUM_OPTION pOptions
= NULL
;
202 DWORD dwValues
, dwMaxValueNameLen
, dwMaxValueLen
;
203 DWORD dwValueNameLength
, dwValueLength
;
207 dwError
= RegOpenKeyExW(hKey
,
212 if (dwError
!= ERROR_SUCCESS
)
215 dwError
= RegQueryInfoKeyW(hEnumKey
,
227 if (dwError
!= ERROR_SUCCESS
)
229 ERR("RegQueryInfoKeyW failed (Error %lu)\n", dwError
);
233 pOptions
= HeapAlloc(GetProcessHeap(),
235 dwValues
* sizeof(ENUM_OPTION
));
236 if (pOptions
== NULL
)
238 dwError
= ERROR_OUTOFMEMORY
;
242 for (i
= 0; i
< dwValues
; i
++)
244 dwValueNameLength
= dwMaxValueNameLen
+ sizeof(WCHAR
);
245 pOptions
[i
].pszValue
= HeapAlloc(GetProcessHeap(),
247 dwValueNameLength
* sizeof(WCHAR
));
248 if (pOptions
[i
].pszValue
== NULL
)
250 dwError
= ERROR_OUTOFMEMORY
;
254 dwValueLength
= dwMaxValueLen
;
255 pOptions
[i
].pszName
= HeapAlloc(GetProcessHeap(),
258 if (pOptions
[i
].pszName
== NULL
)
260 dwError
= ERROR_OUTOFMEMORY
;
264 dwError
= RegEnumValueW(hEnumKey
,
266 pOptions
[i
].pszValue
,
270 (PBYTE
)pOptions
[i
].pszName
,
272 if (dwError
== ERROR_NO_MORE_ITEMS
)
274 dwError
== ERROR_SUCCESS
;
277 else if (dwError
!= ERROR_SUCCESS
)
283 pParameter
->pEnumOptions
= pOptions
;
284 pParameter
->dwEnumOptions
= dwValues
;
288 if (pOptions
!= NULL
)
290 for (i
= 0; i
< dwValues
; i
++)
292 if (pOptions
[i
].pszValue
!= NULL
)
293 HeapFree(GetProcessHeap(), 0, pOptions
[i
].pszValue
);
295 if (pOptions
[i
].pszName
!= NULL
)
296 HeapFree(GetProcessHeap(), 0, pOptions
[i
].pszName
);
299 HeapFree(GetProcessHeap(), 0, pOptions
);
302 if (hEnumKey
!= NULL
)
303 RegCloseKey(hEnumKey
);
312 _In_ PPARAMETER pParameter
,
317 if ((pParameter
->pEnumOptions
== NULL
) ||
318 (pParameter
->dwEnumOptions
== 0))
321 for (i
= 0; i
< pParameter
->dwEnumOptions
; i
++)
323 if (_wcsicmp(pParameter
->pEnumOptions
[i
].pszValue
, pszValue
) == 0)
334 _In_ HDEVINFO DeviceInfoSet
,
335 _In_ PSP_DEVINFO_DATA DeviceInfoData
,
336 _Out_ PPARAMETER_ARRAY
*ParameterArray
)
338 HKEY hDriverKey
= INVALID_HANDLE_VALUE
;
339 HKEY hParamsKey
= INVALID_HANDLE_VALUE
;
341 PPARAMETER_ARRAY ParamArray
= NULL
;
342 DWORD dwSubKeys
, dwMaxSubKeyLen
, dwKeyLen
, dwIndex
;
343 PWSTR pszType
= NULL
;
347 hDriverKey
= SetupDiOpenDevRegKey(DeviceInfoSet
,
353 if (hDriverKey
== INVALID_HANDLE_VALUE
)
355 ERR("SetupDiOpenDevRegKey() failed\n");
359 lError
= RegOpenKeyExW(hDriverKey
,
364 if (lError
!= ERROR_SUCCESS
)
366 ERR("RegOpenKeyExW failed (Error %lu)\n", lError
);
370 lError
= RegQueryInfoKeyW(hParamsKey
,
382 if (lError
!= ERROR_SUCCESS
)
384 ERR("RegOpenKeyExW failed (Error %lu)\n", lError
);
388 FIXME("Sub keys: %lu\n", dwSubKeys
);
392 TRACE("No sub keys. Done!\n");
396 ParamArray
= HeapAlloc(GetProcessHeap(),
398 sizeof(PARAMETER_ARRAY
) + (dwSubKeys
* sizeof(PARAMETER
)));
399 if (ParamArray
== NULL
)
401 ERR("Parameter array allocation failed!\n");
405 ParamArray
->dwCount
= dwSubKeys
;
409 for (dwIndex
= 0; dwIndex
< dwSubKeys
; dwIndex
++)
411 ParamArray
->Array
[dwIndex
].pszName
= HeapAlloc(GetProcessHeap(),
413 dwMaxSubKeyLen
* sizeof(WCHAR
));
414 if (ParamArray
->Array
[dwIndex
].pszName
== NULL
)
416 ERR("Parameter array allocation failed!\n");
420 dwKeyLen
= dwMaxSubKeyLen
;
421 lError
= RegEnumKeyExW(hParamsKey
,
423 ParamArray
->Array
[dwIndex
].pszName
,
429 if (lError
!= ERROR_SUCCESS
)
432 FIXME("Sub key '%S'\n", ParamArray
->Array
[dwIndex
].pszName
);
434 lError
= RegOpenKeyExW(hParamsKey
,
435 ParamArray
->Array
[dwIndex
].pszName
,
439 if (lError
== ERROR_SUCCESS
)
441 GetStringValue(hParamKey
,
443 &ParamArray
->Array
[dwIndex
].pszDescription
);
445 GetStringValue(hParamKey
,
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
;
463 ParamArray
->Array
[dwIndex
].Type
= NO_TYPE
;
465 HeapFree(GetProcessHeap(), 0, pszType
);
469 GetStringValue(hParamKey
,
471 &ParamArray
->Array
[dwIndex
].pszDefault
);
473 GetBooleanValue(hParamKey
,
476 &ParamArray
->Array
[dwIndex
].bOptional
);
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
)
483 /* FIXME: Read Base, Min, Max and Step values */
485 else if (ParamArray
->Array
[dwIndex
].Type
== EDIT_TYPE
)
487 GetBooleanValue(hParamKey
,
490 &ParamArray
->Array
[dwIndex
].bUpperCase
);
492 GetIntValue(hParamKey
,
495 &ParamArray
->Array
[dwIndex
].iTextLimit
);
497 else if (ParamArray
->Array
[dwIndex
].Type
== ENUM_TYPE
)
499 GetEnumOptions(hParamKey
,
500 &ParamArray
->Array
[dwIndex
]);
503 RegCloseKey(hParamKey
);
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
))
512 ParamArray
->Array
[dwIndex
].bPresent
= TRUE
;
516 *ParameterArray
= ParamArray
;
520 if (ret
== FALSE
&& ParamArray
!= NULL
)
521 FreeParameterArray(ParamArray
);
523 if (hParamsKey
!= INVALID_HANDLE_VALUE
)
524 RegCloseKey(hParamsKey
);
526 if (hDriverKey
!= INVALID_HANDLE_VALUE
)
527 RegCloseKey(hDriverKey
);
537 PPARAMETER Parameter
)
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
)
548 if (Parameter
->bPresent
)
549 Button_SetCheck(GetDlgItem(hwnd
, IDC_PROPERTY_PRESENT
), BST_CHECKED
);
551 Button_SetCheck(GetDlgItem(hwnd
, IDC_PROPERTY_NOT_PRESENT
), BST_CHECKED
);
554 switch (Parameter
->Type
)
560 ShowWindow(GetDlgItem(hwnd
, IDC_PROPERTY_VALUE_LIST
), SW_HIDE
);
562 hwndControl
= GetDlgItem(hwnd
, IDC_PROPERTY_VALUE_UPDN
);
563 EnableWindow(hwndControl
, Parameter
->bPresent
);
564 ShowWindow(hwndControl
, SW_SHOW
);
566 hwndControl
= GetDlgItem(hwnd
, IDC_PROPERTY_VALUE_EDIT
);
567 EnableWindow(hwndControl
, Parameter
->bPresent
);
568 ShowWindow(hwndControl
, SW_SHOW
);
570 Style
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
572 SetWindowLongPtr(hwndControl
, GWL_STYLE
, Style
);
574 Edit_LimitText(hwndControl
, 0);
576 if (Parameter
->pszValue
)
577 Edit_SetText(hwndControl
, Parameter
->pszValue
);
578 else if (Parameter
->pszDefault
)
579 Edit_SetText(hwndControl
, Parameter
->pszDefault
);
583 ShowWindow(GetDlgItem(hwnd
, IDC_PROPERTY_VALUE_UPDN
), SW_HIDE
);
584 ShowWindow(GetDlgItem(hwnd
, IDC_PROPERTY_VALUE_LIST
), SW_HIDE
);
586 hwndControl
= GetDlgItem(hwnd
, IDC_PROPERTY_VALUE_EDIT
);
587 EnableWindow(hwndControl
, Parameter
->bPresent
);
588 ShowWindow(hwndControl
, SW_SHOW
);
590 Style
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
592 if (Parameter
->bUpperCase
)
593 Style
|= ES_UPPERCASE
;
595 Style
&= ~ES_UPPERCASE
;
596 SetWindowLongPtr(hwndControl
, GWL_STYLE
, Style
);
598 Edit_LimitText(hwndControl
, Parameter
->iTextLimit
);
600 if (Parameter
->pszValue
)
601 Edit_SetText(hwndControl
, Parameter
->pszValue
);
602 else if (Parameter
->pszDefault
)
603 Edit_SetText(hwndControl
, Parameter
->pszDefault
);
607 ShowWindow(GetDlgItem(hwnd
, IDC_PROPERTY_VALUE_EDIT
), SW_HIDE
);
608 ShowWindow(GetDlgItem(hwnd
, IDC_PROPERTY_VALUE_UPDN
), SW_HIDE
);
610 hwndControl
= GetDlgItem(hwnd
, IDC_PROPERTY_VALUE_LIST
);
611 EnableWindow(hwndControl
, Parameter
->bPresent
);
612 ShowWindow(hwndControl
, SW_SHOW
);
614 ComboBox_ResetContent(hwndControl
);
616 if (Parameter
->pEnumOptions
!= NULL
&& Parameter
->dwEnumOptions
!= 0)
618 for (i
= 0; i
< Parameter
->dwEnumOptions
; i
++)
620 ComboBox_AddString(hwndControl
, Parameter
->pEnumOptions
[i
].pszName
);
624 if (Parameter
->pszValue
)
626 idx
= FindEnumOption(Parameter
, Parameter
->pszValue
);
628 ComboBox_SetCurSel(hwndControl
, idx
);
630 else if (Parameter
->pszDefault
)
632 idx
= FindEnumOption(Parameter
, Parameter
->pszDefault
);
634 ComboBox_SetCurSel(hwndControl
, idx
);
651 PPARAMETER_ARRAY pParamArray
;
656 FIXME("OnInitDialog()\n");
658 pParamArray
= (PPARAMETER_ARRAY
)((LPPROPSHEETPAGEW
)lParam
)->lParam
;
659 if (pParamArray
== NULL
)
661 ERR("pParamArray is NULL\n");
665 SetWindowLongPtr(hwnd
, DWLP_USER
, (LONG_PTR
)pParamArray
);
667 hwndControl
= GetDlgItem(hwnd
, IDC_PROPERTY_NAME
);
670 for (i
= 0; i
< pParamArray
->dwCount
; i
++)
672 if (pParamArray
->Array
[i
].pszDescription
!= NULL
)
673 pszText
= pParamArray
->Array
[i
].pszDescription
;
675 pszText
= pParamArray
->Array
[i
].pszName
;
677 ListBox_AddString(hwndControl
, pszText
);
680 if (pParamArray
->dwCount
> 0)
682 ListBox_SetCurSel(hwndControl
, 0);
683 pParamArray
->pCurrentParam
= &pParamArray
->Array
[0];
684 DisplayParameter(hwnd
, pParamArray
->pCurrentParam
);
699 PPARAMETER_ARRAY pParamArray
;
702 TRACE("OnCommand()\n");
704 pParamArray
= (PPARAMETER_ARRAY
)GetWindowLongPtr(hwnd
, DWLP_USER
);
705 if (pParamArray
== NULL
)
707 ERR("pParamArray is NULL\n");
711 if ((LOWORD(wParam
) == IDC_PROPERTY_NAME
) && (HIWORD(wParam
) == LBN_SELCHANGE
))
713 iIndex
= ListBox_GetCurSel((HWND
)lParam
);
714 if (iIndex
!= LB_ERR
&& iIndex
< pParamArray
->dwCount
)
716 pParamArray
->pCurrentParam
= &pParamArray
->Array
[iIndex
];
717 DisplayParameter(hwnd
, pParamArray
->pCurrentParam
);
720 else if ((LOWORD(wParam
) == IDC_PROPERTY_PRESENT
) && (HIWORD(wParam
) == BN_CLICKED
))
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
;
727 else if ((LOWORD(wParam
) == IDC_PROPERTY_NOT_PRESENT
) && (HIWORD(wParam
) == BN_CLICKED
))
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
;
742 PPARAMETER_ARRAY pParamArray
;
744 FIXME("OnDestroy()\n");
746 pParamArray
= (PPARAMETER_ARRAY
)GetWindowLongPtr(hwnd
, DWLP_USER
);
747 if (pParamArray
== NULL
)
749 ERR("pParamArray is NULL\n");
753 FreeParameterArray(pParamArray
);
754 SetWindowLongPtr(hwnd
, DWLP_USER
, (LONG_PTR
)NULL
);
761 NetPropertyPageDlgProc(
770 return OnInitDialog(hwnd
, wParam
, lParam
);
773 OnCommand(hwnd
, wParam
, lParam
);
791 PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest
,
792 LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc
,
795 PROPSHEETPAGEW PropSheetPage
;
796 HPROPSHEETPAGE hPropSheetPage
;
797 PPARAMETER_ARRAY ParameterArray
= NULL
;
799 ERR("NetPropPageProvider(%p %p %lx)\n",
800 lpPropSheetPageRequest
, lpfnAddPropSheetPageProc
, lParam
);
802 if (!BuildParameterArray(lpPropSheetPageRequest
->DeviceInfoSet
,
803 lpPropSheetPageRequest
->DeviceInfoData
,
807 if (lpPropSheetPageRequest
->PageRequested
== SPPSR_ENUM_ADV_DEVICE_PROPERTIES
)
809 ERR("SPPSR_ENUM_ADV_DEVICE_PROPERTIES\n");
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
;
819 hPropSheetPage
= CreatePropertySheetPageW(&PropSheetPage
);
820 if (hPropSheetPage
== NULL
)
822 ERR("CreatePropertySheetPageW() failed!\n");
826 if (!(*lpfnAddPropSheetPageProc
)(hPropSheetPage
, lParam
))
828 ERR("lpfnAddPropSheetPageProc() failed!\n");
829 DestroyPropertySheetPage(hPropSheetPage
);