fe9f48f8524861ae590b8a6492ae46e05b43213b
[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 _PARAMETER
22 {
23 PWSTR pszName;
24 PWSTR pszDescription;
25 PWSTR pszValue;
26 PWSTR pszDefault;
27 PARAM_TYPE Type;
28 BOOL bUpperCase;
29 BOOL bOptional;
30 INT iLimitText;
31
32 } PARAMETER, *PPARAMETER;
33
34 typedef struct _PARAMETER_ARRAY
35 {
36 DWORD dwCount;
37 PARAMETER Array[0];
38 } PARAMETER_ARRAY, *PPARAMETER_ARRAY;
39
40
41 static
42 VOID
43 FreeParameterArray(
44 _In_ PPARAMETER_ARRAY ParamArray)
45 {
46 INT i;
47
48 if (ParamArray == NULL)
49 return;
50
51 for (i = 0; i < ParamArray->dwCount; i++)
52 {
53 if (ParamArray->Array[i].pszName != NULL)
54 HeapFree(GetProcessHeap(), 0, ParamArray->Array[i].pszName);
55
56 if (ParamArray->Array[i].pszDescription != NULL)
57 HeapFree(GetProcessHeap(), 0, ParamArray->Array[i].pszDescription);
58
59 if (ParamArray->Array[i].pszDefault != NULL)
60 HeapFree(GetProcessHeap(), 0, ParamArray->Array[i].pszDefault);
61
62 }
63
64 HeapFree(GetProcessHeap(), 0, ParamArray);
65 }
66
67
68 static DWORD
69 GetValueString(
70 IN HKEY hKey,
71 IN LPWSTR lpValueName,
72 OUT LPWSTR *lpString)
73 {
74 LPWSTR lpBuffer;
75 DWORD dwLength = 0;
76 DWORD dwRegType;
77 DWORD rc;
78
79 *lpString = NULL;
80
81 RegQueryValueExW(hKey, lpValueName, NULL, &dwRegType, NULL, &dwLength);
82
83 if (dwLength == 0 || dwRegType != REG_SZ)
84 return ERROR_FILE_NOT_FOUND;
85
86 lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength + sizeof(WCHAR));
87 if (lpBuffer == NULL)
88 return ERROR_NOT_ENOUGH_MEMORY;
89
90 rc = RegQueryValueExW(hKey, lpValueName, NULL, NULL, (LPBYTE)lpBuffer, &dwLength);
91 if (rc != ERROR_SUCCESS)
92 {
93 HeapFree(GetProcessHeap(), 0, lpBuffer);
94 return rc;
95 }
96
97 lpBuffer[dwLength / sizeof(WCHAR)] = UNICODE_NULL;
98
99 *lpString = lpBuffer;
100
101 return ERROR_SUCCESS;
102 }
103
104
105 static
106 BOOL
107 BuildParameterArray(
108 _In_ HDEVINFO DeviceInfoSet,
109 _In_ PSP_DEVINFO_DATA DeviceInfoData,
110 _Out_ PPARAMETER_ARRAY *ParameterArray)
111 {
112 HKEY hDriverKey = INVALID_HANDLE_VALUE;
113 HKEY hParamsKey = INVALID_HANDLE_VALUE;
114 HKEY hParamKey;
115 PPARAMETER_ARRAY ParamArray = NULL;
116 DWORD dwSubKeys, dwMaxSubKeyLen, dwKeyLen, dwIndex;
117 PWSTR pszType = NULL;
118 LONG lError;
119 BOOL ret = FALSE;
120
121 hDriverKey = SetupDiOpenDevRegKey(DeviceInfoSet,
122 DeviceInfoData,
123 DICS_FLAG_GLOBAL,
124 0,
125 DIREG_DRV,
126 KEY_READ);
127 if (hDriverKey == INVALID_HANDLE_VALUE)
128 {
129 ERR("SetupDiOpenDevRegKey() failed\n");
130 return FALSE;
131 }
132
133 lError = RegOpenKeyExW(hDriverKey,
134 L"Ndi\\Params",
135 0,
136 KEY_READ,
137 &hParamsKey);
138 if (lError != ERROR_SUCCESS)
139 {
140 ERR("RegOpenKeyExW failed (Error %lu)\n", lError);
141 goto done;
142 }
143
144 lError = RegQueryInfoKeyW(hParamsKey,
145 NULL,
146 NULL,
147 NULL,
148 &dwSubKeys,
149 &dwMaxSubKeyLen,
150 NULL,
151 NULL,
152 NULL,
153 NULL,
154 NULL,
155 NULL);
156 if (lError != ERROR_SUCCESS)
157 {
158 ERR("RegOpenKeyExW failed (Error %lu)\n", lError);
159 goto done;
160 }
161
162 FIXME("Sub keys: %lu\n", dwSubKeys);
163
164 if (dwSubKeys == 0)
165 {
166 TRACE("No sub keys. Done!\n");
167 goto done;
168 }
169
170 ParamArray = HeapAlloc(GetProcessHeap(),
171 HEAP_ZERO_MEMORY,
172 sizeof(PARAMETER_ARRAY) + (dwSubKeys * sizeof(PARAMETER)));
173 if (ParamArray == NULL)
174 {
175 ERR("Parameter array allocation failed!\n");
176 goto done;
177 }
178
179 ParamArray->dwCount = dwSubKeys;
180
181 dwMaxSubKeyLen++;
182
183 for (dwIndex = 0; dwIndex < dwSubKeys; dwIndex++)
184 {
185 ParamArray->Array[dwIndex].pszName = HeapAlloc(GetProcessHeap(),
186 0,
187 dwMaxSubKeyLen * sizeof(WCHAR));
188 if (ParamArray->Array[dwIndex].pszName == NULL)
189 {
190 ERR("Parameter array allocation failed!\n");
191 goto done;
192 }
193
194 dwKeyLen = dwMaxSubKeyLen;
195 lError = RegEnumKeyExW(hParamsKey,
196 dwIndex,
197 ParamArray->Array[dwIndex].pszName,
198 &dwKeyLen,
199 NULL,
200 NULL,
201 NULL,
202 NULL);
203 if (lError != ERROR_SUCCESS)
204 break;
205
206 FIXME("Sub key '%S'\n", ParamArray->Array[dwIndex].pszName);
207
208 lError = RegOpenKeyExW(hParamsKey,
209 ParamArray->Array[dwIndex].pszName,
210 0,
211 KEY_READ,
212 &hParamKey);
213 if (lError == ERROR_SUCCESS)
214 {
215 GetValueString(hParamKey,
216 L"ParamDesc",
217 &ParamArray->Array[dwIndex].pszDescription);
218
219 GetValueString(hParamKey,
220 L"Type",
221 &pszType);
222 if (pszType != NULL)
223 {
224 if (_wcsicmp(pszType, L"int") == 0)
225 ParamArray->Array[dwIndex].Type = INT_TYPE;
226 else if (_wcsicmp(pszType, L"long") == 0)
227 ParamArray->Array[dwIndex].Type = LONG_TYPE;
228 else if (_wcsicmp(pszType, L"word") == 0)
229 ParamArray->Array[dwIndex].Type = WORD_TYPE;
230 else if (_wcsicmp(pszType, L"dword") == 0)
231 ParamArray->Array[dwIndex].Type = DWORD_TYPE;
232 else if (_wcsicmp(pszType, L"edit") == 0)
233 ParamArray->Array[dwIndex].Type = EDIT_TYPE;
234 else if (_wcsicmp(pszType, L"enum") == 0)
235 ParamArray->Array[dwIndex].Type = ENUM_TYPE;
236 else
237 ParamArray->Array[dwIndex].Type = NO_TYPE;
238
239 HeapFree(GetProcessHeap(), 0, pszType);
240 pszType = NULL;
241 }
242
243 GetValueString(hParamKey,
244 L"Default",
245 &ParamArray->Array[dwIndex].pszDefault);
246
247 ParamArray->Array[dwIndex].bUpperCase = FALSE;
248 ParamArray->Array[dwIndex].bOptional = FALSE;
249 ParamArray->Array[dwIndex].iLimitText = 0;
250
251 RegCloseKey(hParamKey);
252 }
253
254 GetValueString(hDriverKey,
255 ParamArray->Array[dwIndex].pszName,
256 &ParamArray->Array[dwIndex].pszValue);
257 }
258
259 *ParameterArray = ParamArray;
260 ret = TRUE;
261
262 done:
263 if (ret == FALSE && ParamArray != NULL)
264 FreeParameterArray(ParamArray);
265
266 if (hParamsKey != INVALID_HANDLE_VALUE)
267 RegCloseKey(hParamsKey);
268
269 if (hDriverKey != INVALID_HANDLE_VALUE)
270 RegCloseKey(hDriverKey);
271
272 return ret;
273 }
274
275
276 static
277 VOID
278 DisplayParameter(
279 HWND hwnd,
280 PPARAMETER Parameter)
281 {
282 LONG_PTR Style;
283
284 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_PRESENT), (Parameter->bOptional) ? SW_SHOW : SW_HIDE);
285 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_NOT_PRESENT), (Parameter->bOptional) ? SW_SHOW : SW_HIDE);
286
287 switch (Parameter->Type)
288 {
289 case INT_TYPE:
290 case LONG_TYPE:
291 case WORD_TYPE:
292 case DWORD_TYPE:
293 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), SW_SHOW);
294 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_UPDN), SW_SHOW);
295 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_LIST), SW_HIDE);
296
297 Style = GetWindowLongPtr(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), GWL_STYLE);
298 Style |= ES_NUMBER;
299 SetWindowLongPtr(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), GWL_STYLE, Style);
300
301 Edit_LimitText(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), 0);
302
303 if (Parameter->pszValue)
304 Edit_SetText(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), Parameter->pszValue);
305 else if (Parameter->pszDefault)
306 Edit_SetText(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), Parameter->pszDefault);
307 break;
308
309 case EDIT_TYPE:
310 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), SW_SHOW);
311 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_UPDN), SW_HIDE);
312 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_LIST), SW_HIDE);
313
314 Style = GetWindowLongPtr(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), GWL_STYLE);
315 Style &= ~ES_NUMBER;
316 if (Parameter->bUpperCase)
317 Style |= ES_UPPERCASE;
318 else
319 Style &= ~ES_UPPERCASE;
320 SetWindowLongPtr(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), GWL_STYLE, Style);
321
322 Edit_LimitText(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), Parameter->iLimitText);
323
324 if (Parameter->pszValue)
325 Edit_SetText(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), Parameter->pszValue);
326 else if (Parameter->pszDefault)
327 Edit_SetText(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), Parameter->pszDefault);
328 break;
329
330 case ENUM_TYPE:
331 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), SW_HIDE);
332 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_UPDN), SW_HIDE);
333 ShowWindow(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_LIST), SW_SHOW);
334
335 if (Parameter->pszValue)
336 Edit_SetText(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), Parameter->pszValue);
337 else if (Parameter->pszDefault)
338 Edit_SetText(GetDlgItem(hwnd, IDC_PROPERTY_VALUE_EDIT), Parameter->pszDefault);
339 break;
340
341 default:
342 break;
343 }
344 }
345
346
347 static
348 BOOL
349 OnInitDialog(
350 HWND hwnd,
351 WPARAM wParam,
352 LPARAM lParam)
353 {
354 PPARAMETER_ARRAY pParamArray;
355 HWND hwndControl;
356 PWSTR pszText;
357 DWORD i;
358
359 FIXME("OnInitDialog()\n");
360
361 pParamArray = (PPARAMETER_ARRAY)((LPPROPSHEETPAGEW)lParam)->lParam;
362 if (pParamArray == NULL)
363 {
364 ERR("pParamArray is NULL\n");
365 return FALSE;
366 }
367
368 SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)pParamArray);
369
370 hwndControl = GetDlgItem(hwnd, IDC_PROPERTY_NAME);
371 if (hwndControl)
372 {
373 for (i = 0; i < pParamArray->dwCount; i++)
374 {
375 if (pParamArray->Array[i].pszDescription != NULL)
376 pszText = pParamArray->Array[i].pszDescription;
377 else
378 pszText = pParamArray->Array[i].pszName;
379
380 ListBox_AddString(hwndControl, pszText);
381 }
382
383 if (pParamArray->dwCount > 0)
384 {
385 ListBox_SetCurSel(hwndControl, 0);
386 DisplayParameter(hwnd, &pParamArray->Array[0]);
387 }
388 }
389
390 return TRUE;
391 }
392
393
394 static
395 VOID
396 OnCommand(
397 HWND hwnd,
398 WPARAM wParam,
399 LPARAM lParam)
400 {
401 PPARAMETER_ARRAY pParamArray;
402 INT iIndex;
403
404 TRACE("OnCommand()\n");
405
406 pParamArray = (PPARAMETER_ARRAY)GetWindowLongPtr(hwnd, DWLP_USER);
407 if (pParamArray == NULL)
408 {
409 ERR("pParamArray is NULL\n");
410 return;
411 }
412
413 if ((LOWORD(wParam) == IDC_PROPERTY_NAME) && (HIWORD(wParam) == LBN_SELCHANGE))
414 {
415 iIndex = ListBox_GetCurSel((HWND)lParam);
416 if (iIndex != LB_ERR && iIndex < pParamArray->dwCount)
417 {
418 DisplayParameter(hwnd, &pParamArray->Array[iIndex]);
419 }
420 }
421 }
422
423
424 static
425 VOID
426 OnDestroy(
427 HWND hwnd)
428 {
429 PPARAMETER_ARRAY pParamArray;
430
431 FIXME("OnDestroy()\n");
432
433 pParamArray = (PPARAMETER_ARRAY)GetWindowLongPtr(hwnd, DWLP_USER);
434 if (pParamArray == NULL)
435 {
436 ERR("pParamArray is NULL\n");
437 return;
438 }
439
440 FreeParameterArray(pParamArray);
441 SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)NULL);
442 }
443
444
445 static
446 INT_PTR
447 CALLBACK
448 NetPropertyPageDlgProc(
449 HWND hwnd,
450 UINT uMsg,
451 WPARAM wParam,
452 LPARAM lParam)
453 {
454 switch (uMsg)
455 {
456 case WM_INITDIALOG:
457 return OnInitDialog(hwnd, wParam, lParam);
458
459 case WM_COMMAND:
460 OnCommand(hwnd, wParam, lParam);
461 break;
462
463 case WM_DESTROY:
464 OnDestroy(hwnd);
465 break;
466
467 default:
468 break;
469 }
470
471 return FALSE;
472 }
473
474
475 BOOL
476 WINAPI
477 NetPropPageProvider(
478 PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest,
479 LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
480 LPARAM lParam)
481 {
482 PROPSHEETPAGEW PropSheetPage;
483 HPROPSHEETPAGE hPropSheetPage;
484 PPARAMETER_ARRAY ParameterArray = NULL;
485
486 ERR("NetPropPageProvider(%p %p %lx)\n",
487 lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam);
488
489 if (!BuildParameterArray(lpPropSheetPageRequest->DeviceInfoSet,
490 lpPropSheetPageRequest->DeviceInfoData,
491 &ParameterArray))
492 return FALSE;
493
494 if (lpPropSheetPageRequest->PageRequested == SPPSR_ENUM_ADV_DEVICE_PROPERTIES)
495 {
496 ERR("SPPSR_ENUM_ADV_DEVICE_PROPERTIES\n");
497
498 PropSheetPage.dwSize = sizeof(PROPSHEETPAGEW);
499 PropSheetPage.dwFlags = 0;
500 PropSheetPage.hInstance = netcfgx_hInstance;
501 PropSheetPage.u.pszTemplate = MAKEINTRESOURCE(IDD_NET_PROPERTY_DLG);
502 PropSheetPage.pfnDlgProc = NetPropertyPageDlgProc;
503 PropSheetPage.lParam = (LPARAM)ParameterArray;
504 PropSheetPage.pfnCallback = NULL;
505
506 hPropSheetPage = CreatePropertySheetPageW(&PropSheetPage);
507 if (hPropSheetPage == NULL)
508 {
509 ERR("CreatePropertySheetPageW() failed!\n");
510 return FALSE;
511 }
512
513 if (!(*lpfnAddPropSheetPageProc)(hPropSheetPage, lParam))
514 {
515 ERR("lpfnAddPropSheetPageProc() failed!\n");
516 DestroyPropertySheetPage(hPropSheetPage);
517 return FALSE;
518 }
519 }
520
521 ERR("Done!\n");
522
523 return TRUE;
524 }
525
526 /* EOF */