2 * PROJECT: ReactOS System Control Panel Applet
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/cpl/sysdm/environment.c
5 * PURPOSE: Environment variable settings
6 * COPYRIGHT: Copyright Eric Kohl
13 typedef struct _VARIABLE_DATA
19 } VARIABLE_DATA
, *PVARIABLE_DATA
;
23 GetSelectedListViewItem(HWND hwndListView
)
28 iCount
= SendMessage(hwndListView
,
34 for (iItem
= 0; iItem
< iCount
; iItem
++)
36 if (SendMessage(hwndListView
,
39 (LPARAM
) LVIS_SELECTED
) == LVIS_SELECTED
)
50 static INT_PTR CALLBACK
51 EditVariableDlgProc(HWND hwndDlg
,
56 PVARIABLE_DATA VarData
;
60 VarData
= (PVARIABLE_DATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
65 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (LONG_PTR
)lParam
);
66 VarData
= (PVARIABLE_DATA
)lParam
;
68 if (VarData
->lpName
!= NULL
)
70 SendDlgItemMessage(hwndDlg
, IDC_VARIABLE_NAME
, WM_SETTEXT
, 0, (LPARAM
)VarData
->lpName
);
73 if (VarData
->lpRawValue
!= NULL
)
75 SendDlgItemMessage(hwndDlg
, IDC_VARIABLE_VALUE
, WM_SETTEXT
, 0, (LPARAM
)VarData
->lpRawValue
);
80 switch (LOWORD(wParam
))
83 dwNameLength
= (DWORD
)SendDlgItemMessage(hwndDlg
, IDC_VARIABLE_NAME
, WM_GETTEXTLENGTH
, 0, 0);
84 dwValueLength
= (DWORD
)SendDlgItemMessage(hwndDlg
, IDC_VARIABLE_VALUE
, WM_GETTEXTLENGTH
, 0, 0);
85 if (dwNameLength
> 0 && dwValueLength
> 0)
89 if (VarData
->lpName
== NULL
)
91 VarData
->lpName
= GlobalAlloc(GPTR
, (dwNameLength
+ 1) * sizeof(TCHAR
));
93 else if (_tcslen(VarData
->lpName
) < dwNameLength
)
95 GlobalFree(VarData
->lpName
);
96 VarData
->lpName
= GlobalAlloc(GPTR
, (dwNameLength
+ 1) * sizeof(TCHAR
));
98 SendDlgItemMessage(hwndDlg
, IDC_VARIABLE_NAME
, WM_GETTEXT
, dwNameLength
+ 1, (LPARAM
)VarData
->lpName
);
100 if (VarData
->lpRawValue
== NULL
)
102 VarData
->lpRawValue
= GlobalAlloc(GPTR
, (dwValueLength
+ 1) * sizeof(TCHAR
));
104 else if (_tcslen(VarData
->lpRawValue
) < dwValueLength
)
106 GlobalFree(VarData
->lpRawValue
);
107 VarData
->lpRawValue
= GlobalAlloc(GPTR
, (dwValueLength
+ 1) * sizeof(TCHAR
));
109 SendDlgItemMessage(hwndDlg
, IDC_VARIABLE_VALUE
, WM_GETTEXT
, dwValueLength
+ 1, (LPARAM
)VarData
->lpRawValue
);
111 if (VarData
->lpCookedValue
!= NULL
)
113 GlobalFree(VarData
->lpCookedValue
);
114 VarData
->lpCookedValue
= NULL
;
117 p
= _tcschr(VarData
->lpRawValue
, _T('%'));
118 if (p
&& _tcschr(++p
, _T('%')))
120 VarData
->dwType
= REG_EXPAND_SZ
;
121 VarData
->lpCookedValue
= GlobalAlloc(GPTR
, 2 * MAX_PATH
* sizeof(TCHAR
));
123 ExpandEnvironmentStrings(VarData
->lpRawValue
,
124 VarData
->lpCookedValue
,
129 VarData
->dwType
= REG_SZ
;
130 VarData
->lpCookedValue
= GlobalAlloc(GPTR
, (dwValueLength
+ 1) * sizeof(TCHAR
));
131 _tcscpy(VarData
->lpCookedValue
, VarData
->lpRawValue
);
134 EndDialog(hwndDlg
, 1);
138 EndDialog(hwndDlg
, 0);
149 GetEnvironmentVariables(HWND hwndListView
,
155 DWORD dwMaxValueNameLength
;
156 DWORD dwMaxValueDataLength
;
164 PVARIABLE_DATA VarData
;
169 if (RegOpenKeyEx(hRootKey
,
176 if (RegQueryInfoKey(hKey
,
184 &dwMaxValueNameLength
,
185 &dwMaxValueDataLength
,
193 lpName
= GlobalAlloc(GPTR
, (dwMaxValueNameLength
+ 1) * sizeof(TCHAR
));
200 lpData
= GlobalAlloc(GPTR
, (dwMaxValueDataLength
+ 1) * sizeof(TCHAR
));
208 lpExpandData
= GlobalAlloc(GPTR
, 2048 * sizeof(TCHAR
));
209 if (lpExpandData
== NULL
)
217 for (i
= 0; i
< dwValues
; i
++)
219 dwNameLength
= dwMaxValueNameLength
+ 1;
220 dwDataLength
= dwMaxValueDataLength
+ 1;
222 if (RegEnumValue(hKey
,
237 if (dwType
!= REG_SZ
&& dwType
!= REG_EXPAND_SZ
)
240 VarData
= GlobalAlloc(GPTR
, sizeof(VARIABLE_DATA
));
242 VarData
->dwType
= dwType
;
244 VarData
->lpName
= GlobalAlloc(GPTR
, (dwNameLength
+ 1) * sizeof(TCHAR
));
245 _tcscpy(VarData
->lpName
, lpName
);
247 VarData
->lpRawValue
= GlobalAlloc(GPTR
, (dwDataLength
+ 1) * sizeof(TCHAR
));
248 _tcscpy(VarData
->lpRawValue
, lpData
);
250 ExpandEnvironmentStrings(lpData
, lpExpandData
, 2048);
252 VarData
->lpCookedValue
= GlobalAlloc(GPTR
, (_tcslen(lpExpandData
) + 1) * sizeof(TCHAR
));
253 _tcscpy(VarData
->lpCookedValue
, lpExpandData
);
255 memset(&lvi
, 0x00, sizeof(lvi
));
256 lvi
.mask
= LVIF_TEXT
| LVIF_STATE
| LVIF_PARAM
;
257 lvi
.lParam
= (LPARAM
)VarData
;
258 lvi
.pszText
= VarData
->lpName
;
259 lvi
.state
= (i
== 0) ? LVIS_SELECTED
: 0;
260 iItem
= ListView_InsertItem(hwndListView
, &lvi
);
262 ListView_SetItemText(hwndListView
, iItem
, 1, VarData
->lpCookedValue
);
265 GlobalFree(lpExpandData
);
273 SetListViewColumns(HWND hwndListView
)
279 GetClientRect(hwndListView
, &rect
);
281 memset(&column
, 0x00, sizeof(column
));
282 column
.mask
=LVCF_FMT
| LVCF_WIDTH
| LVCF_SUBITEM
| LVCF_TEXT
;
283 column
.fmt
=LVCFMT_LEFT
;
284 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.32);
286 LoadString(hApplet
, IDS_VARIABLE
, szStr
, sizeof(szStr
) / sizeof(szStr
[0]));
287 column
.pszText
= szStr
;
288 (void)ListView_InsertColumn(hwndListView
, 0, &column
);
290 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.63);
292 LoadString(hApplet
, IDS_VALUE
, szStr
, sizeof(szStr
) / sizeof(szStr
[0]));
293 column
.pszText
= szStr
;
294 (void)ListView_InsertColumn(hwndListView
, 1, &column
);
299 OnInitDialog(HWND hwndDlg
)
303 /* Set user environment variables */
304 hwndListView
= GetDlgItem(hwndDlg
, IDC_USER_VARIABLE_LIST
);
306 (void)ListView_SetExtendedListViewStyle(hwndListView
, LVS_EX_FULLROWSELECT
);
308 SetListViewColumns(hwndListView
);
310 GetEnvironmentVariables(hwndListView
,
314 (void)ListView_SetColumnWidth(hwndListView
, 2, LVSCW_AUTOSIZE_USEHEADER
);
316 ListView_SetItemState(hwndListView
, 0,
317 LVIS_FOCUSED
| LVIS_SELECTED
,
318 LVIS_FOCUSED
| LVIS_SELECTED
);
320 (void)ListView_Update(hwndListView
,0);
322 /* Set system environment variables */
323 hwndListView
= GetDlgItem(hwndDlg
, IDC_SYSTEM_VARIABLE_LIST
);
325 (void)ListView_SetExtendedListViewStyle(hwndListView
, LVS_EX_FULLROWSELECT
);
327 SetListViewColumns(hwndListView
);
329 GetEnvironmentVariables(hwndListView
,
331 _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"));
333 (void)ListView_SetColumnWidth(hwndListView
, 2, LVSCW_AUTOSIZE_USEHEADER
);
335 ListView_SetItemState(hwndListView
, 0,
336 LVIS_FOCUSED
| LVIS_SELECTED
,
337 LVIS_FOCUSED
| LVIS_SELECTED
);
339 (void)ListView_Update(hwndListView
, 0);
344 OnNewVariable(HWND hwndDlg
,
348 PVARIABLE_DATA VarData
;
352 hwndListView
= GetDlgItem(hwndDlg
, iDlgItem
);
354 VarData
= GlobalAlloc(GPTR
, sizeof(VARIABLE_DATA
));
356 if (!DialogBoxParam(hApplet
,
357 MAKEINTRESOURCE(IDD_EDIT_VARIABLE
),
359 (DLGPROC
)EditVariableDlgProc
,
360 (LPARAM
)VarData
) > 0)
362 if (VarData
->lpName
!= NULL
)
363 GlobalFree(VarData
->lpName
);
365 if (VarData
->lpRawValue
!= NULL
)
366 GlobalFree(VarData
->lpRawValue
);
368 if (VarData
->lpCookedValue
!= NULL
)
369 GlobalFree(VarData
->lpCookedValue
);
375 if (VarData
->lpName
!= NULL
&& (VarData
->lpCookedValue
|| VarData
->lpRawValue
))
377 memset(&lvi
, 0x00, sizeof(lvi
));
378 lvi
.mask
= LVIF_TEXT
| LVIF_STATE
| LVIF_PARAM
;
379 lvi
.lParam
= (LPARAM
)VarData
;
380 lvi
.pszText
= VarData
->lpName
;
382 iItem
= ListView_InsertItem(hwndListView
, &lvi
);
384 ListView_SetItemText(hwndListView
, iItem
, 1, VarData
->lpCookedValue
);
391 OnEditVariable(HWND hwndDlg
,
395 PVARIABLE_DATA VarData
;
399 hwndListView
= GetDlgItem(hwndDlg
, iDlgItem
);
401 iItem
= GetSelectedListViewItem(hwndListView
);
404 memset(&lvi
, 0x00, sizeof(lvi
));
405 lvi
.mask
= LVIF_PARAM
;
408 if (ListView_GetItem(hwndListView
, &lvi
))
410 VarData
= (PVARIABLE_DATA
)lvi
.lParam
;
412 if (DialogBoxParam(hApplet
,
413 MAKEINTRESOURCE(IDD_EDIT_VARIABLE
),
415 (DLGPROC
)EditVariableDlgProc
,
416 (LPARAM
)VarData
) > 0)
418 ListView_SetItemText(hwndListView
, iItem
, 0, VarData
->lpName
);
419 ListView_SetItemText(hwndListView
, iItem
, 1, VarData
->lpCookedValue
);
427 OnDeleteVariable(HWND hwndDlg
,
431 PVARIABLE_DATA VarData
;
435 hwndListView
= GetDlgItem(hwndDlg
, iDlgItem
);
437 iItem
= GetSelectedListViewItem(hwndListView
);
440 memset(&lvi
, 0x00, sizeof(lvi
));
441 lvi
.mask
= LVIF_PARAM
;
444 if (ListView_GetItem(hwndListView
, &lvi
))
446 VarData
= (PVARIABLE_DATA
)lvi
.lParam
;
449 if (VarData
->lpName
!= NULL
)
450 GlobalFree(VarData
->lpName
);
452 if (VarData
->lpRawValue
!= NULL
)
453 GlobalFree(VarData
->lpRawValue
);
455 if (VarData
->lpCookedValue
!= NULL
)
456 GlobalFree(VarData
->lpCookedValue
);
463 (void)ListView_DeleteItem(hwndListView
, iItem
);
465 /* Select the previous item */
469 ListView_SetItemState(hwndListView
, iItem
,
470 LVIS_FOCUSED
| LVIS_SELECTED
,
471 LVIS_FOCUSED
| LVIS_SELECTED
);
477 ReleaseListViewItems(HWND hwndDlg
,
481 PVARIABLE_DATA VarData
;
486 hwndListView
= GetDlgItem(hwndDlg
, iDlgItem
);
488 memset(&lvi
, 0x00, sizeof(lvi
));
490 nItemCount
= ListView_GetItemCount(hwndListView
);
491 for (i
= 0; i
< nItemCount
; i
++)
493 lvi
.mask
= LVIF_PARAM
;
496 if (ListView_GetItem(hwndListView
, &lvi
))
498 VarData
= (PVARIABLE_DATA
)lvi
.lParam
;
501 if (VarData
->lpName
!= NULL
)
502 GlobalFree(VarData
->lpName
);
504 if (VarData
->lpRawValue
!= NULL
)
505 GlobalFree(VarData
->lpRawValue
);
507 if (VarData
->lpCookedValue
!= NULL
)
508 GlobalFree(VarData
->lpCookedValue
);
519 SetAllVars(HWND hwndDlg
,
523 PVARIABLE_DATA VarData
;
528 DWORD dwMaxValueNameLength
;
535 memset(&lvi
, 0x00, sizeof(lvi
));
537 /* Get the handle to the list box with all system vars in it */
538 hwndListView
= GetDlgItem(hwndDlg
, iDlgItem
);
539 /* first item is 0 */
541 /* set up struct to retreive item */
542 lvi
.mask
= LVIF_PARAM
;
545 /* Open or create the key */
546 if (RegCreateKeyEx((iDlgItem
== IDC_SYSTEM_VARIABLE_LIST
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
),
547 (iDlgItem
== IDC_SYSTEM_VARIABLE_LIST
? _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment") : _T("Environment")),
550 REG_OPTION_NON_VOLATILE
,
551 KEY_WRITE
| KEY_READ
,
559 /* Get the number of values and the maximum value name length */
560 if (RegQueryInfoKey(hKey
,
568 &dwMaxValueNameLength
,
577 if (dwValueCount
> 0)
579 /* Allocate the value array */
580 aValueArray
= GlobalAlloc(GPTR
, dwValueCount
* sizeof(LPTSTR
));
581 if (aValueArray
!= NULL
)
583 /* Get all value names */
584 for (i
= 0; i
< dwValueCount
; i
++)
587 if (!RegEnumValue(hKey
,
596 /* Allocate a value name buffer, fill it and attach it to the array */
597 lpBuffer
= (LPTSTR
)GlobalAlloc(GPTR
, (dwNameLength
+ 1) * sizeof(TCHAR
));
598 if (lpBuffer
!= NULL
)
600 _tcscpy(lpBuffer
, szBuffer
);
601 aValueArray
[i
] = lpBuffer
;
606 /* Delete all values */
607 for (i
= 0; i
< dwValueCount
; i
++)
609 if (aValueArray
[i
] != NULL
)
611 /* Delete the value*/
615 /* Free the value name */
616 GlobalFree(aValueArray
[i
]);
620 /* Free the value array */
621 GlobalFree(aValueArray
);
625 /* Loop through all variables */
626 while (ListView_GetItem(hwndListView
, &lvi
))
628 /* Get the data in each item */
629 VarData
= (PVARIABLE_DATA
)lvi
.lParam
;
632 /* Set the new value */
633 if (RegSetValueEx(hKey
,
637 (LPBYTE
)VarData
->lpRawValue
,
638 (DWORD
)(_tcslen(VarData
->lpRawValue
) + 1) * sizeof(TCHAR
)))
645 /* Fill struct for next item */
646 lvi
.mask
= LVIF_PARAM
;
655 OnNotify(HWND hwndDlg
, NMHDR
*phdr
)
660 if (phdr
->idFrom
== IDC_USER_VARIABLE_LIST
||
661 phdr
->idFrom
== IDC_SYSTEM_VARIABLE_LIST
)
663 OnEditVariable(hwndDlg
, (INT
)phdr
->idFrom
);
669 if (((LPNMLVKEYDOWN
)phdr
)->wVKey
== VK_DELETE
&&
670 (phdr
->idFrom
== IDC_USER_VARIABLE_LIST
||
671 phdr
->idFrom
== IDC_SYSTEM_VARIABLE_LIST
))
673 OnDeleteVariable(hwndDlg
, (INT
)phdr
->idFrom
);
683 /* Environment dialog procedure */
685 EnvironmentDlgProc(HWND hwndDlg
,
693 OnInitDialog(hwndDlg
);
697 switch (LOWORD(wParam
))
699 case IDC_USER_VARIABLE_NEW
:
700 OnNewVariable(hwndDlg
, IDC_USER_VARIABLE_LIST
);
703 case IDC_USER_VARIABLE_EDIT
:
704 OnEditVariable(hwndDlg
, IDC_USER_VARIABLE_LIST
);
707 case IDC_USER_VARIABLE_DELETE
:
708 OnDeleteVariable(hwndDlg
, IDC_USER_VARIABLE_LIST
);
711 case IDC_SYSTEM_VARIABLE_NEW
:
712 OnNewVariable(hwndDlg
, IDC_SYSTEM_VARIABLE_LIST
);
715 case IDC_SYSTEM_VARIABLE_EDIT
:
716 OnEditVariable(hwndDlg
, IDC_SYSTEM_VARIABLE_LIST
);
719 case IDC_SYSTEM_VARIABLE_DELETE
:
720 OnDeleteVariable(hwndDlg
, IDC_SYSTEM_VARIABLE_LIST
);
724 SetAllVars(hwndDlg
, IDC_USER_VARIABLE_LIST
);
725 SetAllVars(hwndDlg
, IDC_SYSTEM_VARIABLE_LIST
);
726 SendMessage(HWND_BROADCAST
, WM_WININICHANGE
,
727 0, (LPARAM
)_T("Environment"));
728 EndDialog(hwndDlg
, 0);
732 EndDialog(hwndDlg
, 0);
738 ReleaseListViewItems(hwndDlg
, IDC_USER_VARIABLE_LIST
);
739 ReleaseListViewItems(hwndDlg
, IDC_SYSTEM_VARIABLE_LIST
);
743 return OnNotify(hwndDlg
, (NMHDR
*)lParam
);