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
12 typedef struct _VARIABLE_DATA
18 } VARIABLE_DATA
, *PVARIABLE_DATA
;
22 GetSelectedListViewItem(HWND hwndListView
)
27 iCount
= SendMessage(hwndListView
,
33 for (iItem
= 0; iItem
< iCount
; iItem
++)
35 if (SendMessage(hwndListView
,
38 (LPARAM
) LVIS_SELECTED
) == LVIS_SELECTED
)
49 static INT_PTR CALLBACK
50 EditVariableDlgProc(HWND hwndDlg
,
55 PVARIABLE_DATA VarData
;
59 VarData
= (PVARIABLE_DATA
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
64 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (LONG_PTR
)lParam
);
65 VarData
= (PVARIABLE_DATA
)lParam
;
67 if (VarData
->lpName
!= NULL
)
69 SendDlgItemMessage(hwndDlg
, IDC_VARIABLE_NAME
, WM_SETTEXT
, 0, (LPARAM
)VarData
->lpName
);
72 if (VarData
->lpRawValue
!= NULL
)
74 SendDlgItemMessage(hwndDlg
, IDC_VARIABLE_VALUE
, WM_SETTEXT
, 0, (LPARAM
)VarData
->lpRawValue
);
79 switch (LOWORD(wParam
))
82 dwNameLength
= (DWORD
)SendDlgItemMessage(hwndDlg
, IDC_VARIABLE_NAME
, WM_GETTEXTLENGTH
, 0, 0);
83 dwValueLength
= (DWORD
)SendDlgItemMessage(hwndDlg
, IDC_VARIABLE_VALUE
, WM_GETTEXTLENGTH
, 0, 0);
84 if (dwNameLength
> 0 && dwValueLength
> 0)
88 if (VarData
->lpName
== NULL
)
90 VarData
->lpName
= GlobalAlloc(GPTR
, (dwNameLength
+ 1) * sizeof(TCHAR
));
92 else if (_tcslen(VarData
->lpName
) < dwNameLength
)
94 GlobalFree(VarData
->lpName
);
95 VarData
->lpName
= GlobalAlloc(GPTR
, (dwNameLength
+ 1) * sizeof(TCHAR
));
97 SendDlgItemMessage(hwndDlg
, IDC_VARIABLE_NAME
, WM_GETTEXT
, dwNameLength
+ 1, (LPARAM
)VarData
->lpName
);
99 if (VarData
->lpRawValue
== NULL
)
101 VarData
->lpRawValue
= GlobalAlloc(GPTR
, (dwValueLength
+ 1) * sizeof(TCHAR
));
103 else if (_tcslen(VarData
->lpRawValue
) < dwValueLength
)
105 GlobalFree(VarData
->lpRawValue
);
106 VarData
->lpRawValue
= GlobalAlloc(GPTR
, (dwValueLength
+ 1) * sizeof(TCHAR
));
108 SendDlgItemMessage(hwndDlg
, IDC_VARIABLE_VALUE
, WM_GETTEXT
, dwValueLength
+ 1, (LPARAM
)VarData
->lpRawValue
);
110 if (VarData
->lpCookedValue
!= NULL
)
112 GlobalFree(VarData
->lpCookedValue
);
113 VarData
->lpCookedValue
= NULL
;
116 p
= _tcschr(VarData
->lpRawValue
, _T('%'));
117 if (p
&& _tcschr(++p
, _T('%')))
119 VarData
->dwType
= REG_EXPAND_SZ
;
120 VarData
->lpCookedValue
= GlobalAlloc(GPTR
, 2 * MAX_PATH
* sizeof(TCHAR
));
122 ExpandEnvironmentStrings(VarData
->lpRawValue
,
123 VarData
->lpCookedValue
,
128 VarData
->dwType
= REG_SZ
;
129 VarData
->lpCookedValue
= GlobalAlloc(GPTR
, (dwValueLength
+ 1) * sizeof(TCHAR
));
130 _tcscpy(VarData
->lpCookedValue
, VarData
->lpRawValue
);
133 EndDialog(hwndDlg
, 1);
137 EndDialog(hwndDlg
, 0);
148 GetEnvironmentVariables(HWND hwndListView
,
154 DWORD dwMaxValueNameLength
;
155 DWORD dwMaxValueDataLength
;
163 PVARIABLE_DATA VarData
;
168 if (RegOpenKeyEx(hRootKey
,
175 if (RegQueryInfoKey(hKey
,
183 &dwMaxValueNameLength
,
184 &dwMaxValueDataLength
,
192 lpName
= GlobalAlloc(GPTR
, (dwMaxValueNameLength
+ 1) * sizeof(TCHAR
));
199 lpData
= GlobalAlloc(GPTR
, (dwMaxValueDataLength
+ 1) * sizeof(TCHAR
));
207 lpExpandData
= GlobalAlloc(GPTR
, 2048 * sizeof(TCHAR
));
208 if (lpExpandData
== NULL
)
216 for (i
= 0; i
< dwValues
; i
++)
218 dwNameLength
= dwMaxValueNameLength
+ 1;
219 dwDataLength
= dwMaxValueDataLength
+ 1;
221 if (RegEnumValue(hKey
,
236 if (dwType
!= REG_SZ
&& dwType
!= REG_EXPAND_SZ
)
239 VarData
= GlobalAlloc(GPTR
, sizeof(VARIABLE_DATA
));
241 VarData
->dwType
= dwType
;
243 VarData
->lpName
= GlobalAlloc(GPTR
, (dwNameLength
+ 1) * sizeof(TCHAR
));
244 _tcscpy(VarData
->lpName
, lpName
);
246 VarData
->lpRawValue
= GlobalAlloc(GPTR
, (dwDataLength
+ 1) * sizeof(TCHAR
));
247 _tcscpy(VarData
->lpRawValue
, lpData
);
249 ExpandEnvironmentStrings(lpData
, lpExpandData
, 2048);
251 VarData
->lpCookedValue
= GlobalAlloc(GPTR
, (_tcslen(lpExpandData
) + 1) * sizeof(TCHAR
));
252 _tcscpy(VarData
->lpCookedValue
, lpExpandData
);
254 memset(&lvi
, 0x00, sizeof(lvi
));
255 lvi
.mask
= LVIF_TEXT
| LVIF_STATE
| LVIF_PARAM
;
256 lvi
.lParam
= (LPARAM
)VarData
;
257 lvi
.pszText
= VarData
->lpName
;
258 lvi
.state
= (i
== 0) ? LVIS_SELECTED
: 0;
259 iItem
= ListView_InsertItem(hwndListView
, &lvi
);
261 ListView_SetItemText(hwndListView
, iItem
, 1, VarData
->lpCookedValue
);
264 GlobalFree(lpExpandData
);
272 SetListViewColumns(HWND hwndListView
)
278 GetClientRect(hwndListView
, &rect
);
280 memset(&column
, 0x00, sizeof(column
));
281 column
.mask
=LVCF_FMT
| LVCF_WIDTH
| LVCF_SUBITEM
| LVCF_TEXT
;
282 column
.fmt
=LVCFMT_LEFT
;
283 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.32);
285 LoadString(hApplet
, IDS_VARIABLE
, szStr
, sizeof(szStr
) / sizeof(szStr
[0]));
286 column
.pszText
= szStr
;
287 (void)ListView_InsertColumn(hwndListView
, 0, &column
);
289 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.63);
291 LoadString(hApplet
, IDS_VALUE
, szStr
, sizeof(szStr
) / sizeof(szStr
[0]));
292 column
.pszText
= szStr
;
293 (void)ListView_InsertColumn(hwndListView
, 1, &column
);
298 OnInitDialog(HWND hwndDlg
)
302 /* Set user environment variables */
303 hwndListView
= GetDlgItem(hwndDlg
, IDC_USER_VARIABLE_LIST
);
305 (void)ListView_SetExtendedListViewStyle(hwndListView
, LVS_EX_FULLROWSELECT
);
307 SetListViewColumns(hwndListView
);
309 GetEnvironmentVariables(hwndListView
,
313 (void)ListView_SetColumnWidth(hwndListView
, 2, LVSCW_AUTOSIZE_USEHEADER
);
315 ListView_SetItemState(hwndListView
, 0,
316 LVIS_FOCUSED
| LVIS_SELECTED
,
317 LVIS_FOCUSED
| LVIS_SELECTED
);
319 (void)ListView_Update(hwndListView
,0);
321 /* Set system environment variables */
322 hwndListView
= GetDlgItem(hwndDlg
, IDC_SYSTEM_VARIABLE_LIST
);
324 (void)ListView_SetExtendedListViewStyle(hwndListView
, LVS_EX_FULLROWSELECT
);
326 SetListViewColumns(hwndListView
);
328 GetEnvironmentVariables(hwndListView
,
330 _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"));
332 (void)ListView_SetColumnWidth(hwndListView
, 2, LVSCW_AUTOSIZE_USEHEADER
);
334 ListView_SetItemState(hwndListView
, 0,
335 LVIS_FOCUSED
| LVIS_SELECTED
,
336 LVIS_FOCUSED
| LVIS_SELECTED
);
338 (void)ListView_Update(hwndListView
, 0);
343 OnNewVariable(HWND hwndDlg
,
347 PVARIABLE_DATA VarData
;
351 hwndListView
= GetDlgItem(hwndDlg
, iDlgItem
);
353 VarData
= GlobalAlloc(GPTR
, sizeof(VARIABLE_DATA
));
355 if (!DialogBoxParam(hApplet
,
356 MAKEINTRESOURCE(IDD_EDIT_VARIABLE
),
358 (DLGPROC
)EditVariableDlgProc
,
359 (LPARAM
)VarData
) > 0)
361 if (VarData
->lpName
!= NULL
)
362 GlobalFree(VarData
->lpName
);
364 if (VarData
->lpRawValue
!= NULL
)
365 GlobalFree(VarData
->lpRawValue
);
367 if (VarData
->lpCookedValue
!= NULL
)
368 GlobalFree(VarData
->lpCookedValue
);
374 if (VarData
->lpName
!= NULL
&& (VarData
->lpCookedValue
|| VarData
->lpRawValue
))
376 memset(&lvi
, 0x00, sizeof(lvi
));
377 lvi
.mask
= LVIF_TEXT
| LVIF_STATE
| LVIF_PARAM
;
378 lvi
.lParam
= (LPARAM
)VarData
;
379 lvi
.pszText
= VarData
->lpName
;
381 iItem
= ListView_InsertItem(hwndListView
, &lvi
);
383 ListView_SetItemText(hwndListView
, iItem
, 1, VarData
->lpCookedValue
);
390 OnEditVariable(HWND hwndDlg
,
394 PVARIABLE_DATA VarData
;
398 hwndListView
= GetDlgItem(hwndDlg
, iDlgItem
);
400 iItem
= GetSelectedListViewItem(hwndListView
);
403 memset(&lvi
, 0x00, sizeof(lvi
));
404 lvi
.mask
= LVIF_PARAM
;
407 if (ListView_GetItem(hwndListView
, &lvi
))
409 VarData
= (PVARIABLE_DATA
)lvi
.lParam
;
411 if (DialogBoxParam(hApplet
,
412 MAKEINTRESOURCE(IDD_EDIT_VARIABLE
),
414 (DLGPROC
)EditVariableDlgProc
,
415 (LPARAM
)VarData
) > 0)
417 ListView_SetItemText(hwndListView
, iItem
, 0, VarData
->lpName
);
418 ListView_SetItemText(hwndListView
, iItem
, 1, VarData
->lpCookedValue
);
426 OnDeleteVariable(HWND hwndDlg
,
430 PVARIABLE_DATA VarData
;
434 hwndListView
= GetDlgItem(hwndDlg
, iDlgItem
);
436 iItem
= GetSelectedListViewItem(hwndListView
);
439 memset(&lvi
, 0x00, sizeof(lvi
));
440 lvi
.mask
= LVIF_PARAM
;
443 if (ListView_GetItem(hwndListView
, &lvi
))
445 VarData
= (PVARIABLE_DATA
)lvi
.lParam
;
448 if (VarData
->lpName
!= NULL
)
449 GlobalFree(VarData
->lpName
);
451 if (VarData
->lpRawValue
!= NULL
)
452 GlobalFree(VarData
->lpRawValue
);
454 if (VarData
->lpCookedValue
!= NULL
)
455 GlobalFree(VarData
->lpCookedValue
);
462 (void)ListView_DeleteItem(hwndListView
, iItem
);
464 /* Select the previous item */
468 ListView_SetItemState(hwndListView
, iItem
,
469 LVIS_FOCUSED
| LVIS_SELECTED
,
470 LVIS_FOCUSED
| LVIS_SELECTED
);
476 ReleaseListViewItems(HWND hwndDlg
,
480 PVARIABLE_DATA VarData
;
485 hwndListView
= GetDlgItem(hwndDlg
, iDlgItem
);
487 memset(&lvi
, 0x00, sizeof(lvi
));
489 nItemCount
= ListView_GetItemCount(hwndListView
);
490 for (i
= 0; i
< nItemCount
; i
++)
492 lvi
.mask
= LVIF_PARAM
;
495 if (ListView_GetItem(hwndListView
, &lvi
))
497 VarData
= (PVARIABLE_DATA
)lvi
.lParam
;
500 if (VarData
->lpName
!= NULL
)
501 GlobalFree(VarData
->lpName
);
503 if (VarData
->lpRawValue
!= NULL
)
504 GlobalFree(VarData
->lpRawValue
);
506 if (VarData
->lpCookedValue
!= NULL
)
507 GlobalFree(VarData
->lpCookedValue
);
518 SetAllVars(HWND hwndDlg
,
522 PVARIABLE_DATA VarData
;
527 DWORD dwMaxValueNameLength
;
534 memset(&lvi
, 0x00, sizeof(lvi
));
536 /* Get the handle to the list box with all system vars in it */
537 hwndListView
= GetDlgItem(hwndDlg
, iDlgItem
);
538 /* First item is 0 */
540 /* Set up struct to retreive item */
541 lvi
.mask
= LVIF_PARAM
;
544 /* Open or create the key */
545 if (RegCreateKeyEx((iDlgItem
== IDC_SYSTEM_VARIABLE_LIST
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
),
546 (iDlgItem
== IDC_SYSTEM_VARIABLE_LIST
? _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment") : _T("Environment")),
549 REG_OPTION_NON_VOLATILE
,
550 KEY_WRITE
| KEY_READ
,
558 /* Get the number of values and the maximum value name length */
559 if (RegQueryInfoKey(hKey
,
567 &dwMaxValueNameLength
,
576 if (dwValueCount
> 0)
578 /* Allocate the value array */
579 aValueArray
= GlobalAlloc(GPTR
, dwValueCount
* sizeof(LPTSTR
));
580 if (aValueArray
!= NULL
)
582 /* Get all value names */
583 for (i
= 0; i
< dwValueCount
; i
++)
586 if (!RegEnumValue(hKey
,
595 /* Allocate a value name buffer, fill it and attach it to the array */
596 lpBuffer
= (LPTSTR
)GlobalAlloc(GPTR
, (dwNameLength
+ 1) * sizeof(TCHAR
));
597 if (lpBuffer
!= NULL
)
599 _tcscpy(lpBuffer
, szBuffer
);
600 aValueArray
[i
] = lpBuffer
;
605 /* Delete all values */
606 for (i
= 0; i
< dwValueCount
; i
++)
608 if (aValueArray
[i
] != NULL
)
610 /* Delete the value */
614 /* Free the value name */
615 GlobalFree(aValueArray
[i
]);
619 /* Free the value array */
620 GlobalFree(aValueArray
);
624 /* Loop through all variables */
625 while (ListView_GetItem(hwndListView
, &lvi
))
627 /* Get the data in each item */
628 VarData
= (PVARIABLE_DATA
)lvi
.lParam
;
631 /* Set the new value */
632 if (RegSetValueEx(hKey
,
636 (LPBYTE
)VarData
->lpRawValue
,
637 (DWORD
)(_tcslen(VarData
->lpRawValue
) + 1) * sizeof(TCHAR
)))
644 /* Fill struct for next item */
645 lvi
.mask
= LVIF_PARAM
;
654 OnNotify(HWND hwndDlg
, NMHDR
*phdr
)
659 if (phdr
->idFrom
== IDC_USER_VARIABLE_LIST
||
660 phdr
->idFrom
== IDC_SYSTEM_VARIABLE_LIST
)
662 OnEditVariable(hwndDlg
, (INT
)phdr
->idFrom
);
668 if (((LPNMLVKEYDOWN
)phdr
)->wVKey
== VK_DELETE
&&
669 (phdr
->idFrom
== IDC_USER_VARIABLE_LIST
||
670 phdr
->idFrom
== IDC_SYSTEM_VARIABLE_LIST
))
672 OnDeleteVariable(hwndDlg
, (INT
)phdr
->idFrom
);
682 /* Environment dialog procedure */
684 EnvironmentDlgProc(HWND hwndDlg
,
692 OnInitDialog(hwndDlg
);
696 switch (LOWORD(wParam
))
698 case IDC_USER_VARIABLE_NEW
:
699 OnNewVariable(hwndDlg
, IDC_USER_VARIABLE_LIST
);
702 case IDC_USER_VARIABLE_EDIT
:
703 OnEditVariable(hwndDlg
, IDC_USER_VARIABLE_LIST
);
706 case IDC_USER_VARIABLE_DELETE
:
707 OnDeleteVariable(hwndDlg
, IDC_USER_VARIABLE_LIST
);
710 case IDC_SYSTEM_VARIABLE_NEW
:
711 OnNewVariable(hwndDlg
, IDC_SYSTEM_VARIABLE_LIST
);
714 case IDC_SYSTEM_VARIABLE_EDIT
:
715 OnEditVariable(hwndDlg
, IDC_SYSTEM_VARIABLE_LIST
);
718 case IDC_SYSTEM_VARIABLE_DELETE
:
719 OnDeleteVariable(hwndDlg
, IDC_SYSTEM_VARIABLE_LIST
);
723 SetAllVars(hwndDlg
, IDC_USER_VARIABLE_LIST
);
724 SetAllVars(hwndDlg
, IDC_SYSTEM_VARIABLE_LIST
);
725 SendMessage(HWND_BROADCAST
, WM_WININICHANGE
,
726 0, (LPARAM
)_T("Environment"));
727 EndDialog(hwndDlg
, 0);
731 EndDialog(hwndDlg
, 0);
737 ReleaseListViewItems(hwndDlg
, IDC_USER_VARIABLE_LIST
);
738 ReleaseListViewItems(hwndDlg
, IDC_SYSTEM_VARIABLE_LIST
);
742 return OnNotify(hwndDlg
, (NMHDR
*)lParam
);