f348a52a8a1815ff2709e2e30b918072a9ea10e7
[reactos.git] / reactos / dll / cpl / sysdm / environment.c
1 /*
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
7 *
8 */
9
10 #include "precomp.h"
11
12
13 typedef struct _VARIABLE_DATA
14 {
15 LPTSTR lpName;
16 LPTSTR lpRawValue;
17 LPTSTR lpCookedValue;
18 } VARIABLE_DATA, *PVARIABLE_DATA;
19
20
21
22 INT_PTR CALLBACK
23 EditVariableDlgProc(HWND hwndDlg,
24 UINT uMsg,
25 WPARAM wParam,
26 LPARAM lParam)
27 {
28 PVARIABLE_DATA VarData;
29 DWORD dwNameLength;
30 DWORD dwValueLength;
31
32 VarData = (PVARIABLE_DATA)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
33
34 switch (uMsg)
35 {
36 case WM_INITDIALOG:
37 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (LONG_PTR)lParam);
38 VarData = (PVARIABLE_DATA)lParam;
39
40 if (VarData->lpName != NULL)
41 {
42 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_SETTEXT, 0, (LPARAM)VarData->lpName);
43 }
44
45 if (VarData->lpRawValue != NULL)
46 {
47 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_SETTEXT, 0, (LPARAM)VarData->lpRawValue);
48 }
49 break;
50
51 case WM_COMMAND:
52 switch (LOWORD(wParam))
53 {
54 case IDOK:
55 dwNameLength = (DWORD)SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_GETTEXTLENGTH, 0, 0);
56 dwValueLength = (DWORD)SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_GETTEXTLENGTH, 0, 0);
57 if (dwNameLength != 0 && dwValueLength != 0)
58 {
59 if (VarData->lpName == NULL)
60 {
61 VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR));
62 }
63 else if (_tcslen(VarData->lpName) < dwNameLength)
64 {
65 GlobalFree(VarData->lpName);
66 VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR));
67 }
68 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_GETTEXT, dwNameLength + 1, (LPARAM)VarData->lpName);
69
70 if (VarData->lpRawValue == NULL)
71 {
72 VarData->lpRawValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR));
73 }
74 else if (_tcslen(VarData->lpRawValue) < dwValueLength)
75 {
76 GlobalFree(VarData->lpRawValue);
77 VarData->lpRawValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR));
78 }
79 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_GETTEXT, dwValueLength + 1, (LPARAM)VarData->lpRawValue);
80
81 if (_tcschr(VarData->lpRawValue, _T('%')))
82 {
83 if (VarData->lpCookedValue == NULL)
84 {
85 VarData->lpCookedValue = GlobalAlloc(GPTR, 2 * MAX_PATH * sizeof(TCHAR));
86 }
87
88 ExpandEnvironmentStrings(VarData->lpRawValue,
89 VarData->lpCookedValue,
90 2 * MAX_PATH);
91 }
92 else if (VarData->lpCookedValue)
93 {
94 GlobalFree(VarData->lpCookedValue);
95 }
96 }
97 EndDialog(hwndDlg, 1);
98 return TRUE;
99
100 case IDCANCEL:
101 EndDialog(hwndDlg, 0);
102 return TRUE;
103 }
104 break;
105 }
106
107 return FALSE;
108 }
109
110
111 static VOID
112 SetEnvironmentVariables(HWND hwndListView,
113 HKEY hRootKey,
114 LPTSTR lpSubKeyName)
115 {
116 HKEY hKey;
117 DWORD dwValues;
118 DWORD dwMaxValueNameLength;
119 DWORD dwMaxValueDataLength;
120 DWORD i;
121 LPTSTR lpName;
122 LPTSTR lpData;
123 LPTSTR lpExpandData = NULL;
124 DWORD dwNameLength;
125 DWORD dwDataLength;
126 DWORD dwType;
127 PVARIABLE_DATA VarData;
128
129 LV_ITEM lvi;
130 int iItem;
131
132 if (RegOpenKeyEx(hRootKey,
133 lpSubKeyName,
134 0,
135 KEY_READ,
136 &hKey))
137 return;
138
139 if (RegQueryInfoKey(hKey,
140 NULL,
141 NULL,
142 NULL,
143 NULL,
144 NULL,
145 NULL,
146 &dwValues,
147 &dwMaxValueNameLength,
148 &dwMaxValueDataLength,
149 NULL,
150 NULL))
151 {
152 RegCloseKey(hKey);
153 return;
154 }
155
156 lpName = GlobalAlloc(GPTR, (dwMaxValueNameLength + 1) * sizeof(TCHAR));
157 if (lpName == NULL)
158 {
159 RegCloseKey(hKey);
160 return;
161 }
162
163 lpData = GlobalAlloc(GPTR, (dwMaxValueDataLength + 1) * sizeof(TCHAR));
164 if (lpData == NULL)
165 {
166 GlobalFree(lpData);
167 RegCloseKey(hKey);
168 return;
169 }
170
171 for (i = 0; i < dwValues; i++)
172 {
173 dwNameLength = dwMaxValueNameLength + 1;
174 dwDataLength = dwMaxValueDataLength + 1;
175 if (RegEnumValue(hKey,
176 i,
177 lpName,
178 &dwNameLength,
179 NULL,
180 &dwType,
181 (LPBYTE)lpData,
182 &dwDataLength))
183 {
184 GlobalFree(lpName);
185 GlobalFree(lpData);
186 RegCloseKey(hKey);
187 return;
188 }
189
190 VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA));
191
192 VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR));
193 _tcscpy(VarData->lpName, lpName);
194
195 VarData->lpRawValue = GlobalAlloc(GPTR, (dwDataLength + 1) * sizeof(TCHAR));
196 _tcscpy(VarData->lpRawValue, lpData);
197
198 if (dwType == REG_EXPAND_SZ)
199 {
200 lpExpandData = GlobalAlloc(GPTR, MAX_PATH * 2* sizeof(TCHAR));
201 if (lpExpandData == NULL)
202 {
203 GlobalFree(lpName);
204 GlobalFree(lpData);
205 RegCloseKey(hKey);
206 return;
207 }
208
209 ExpandEnvironmentStrings(lpData,
210 lpExpandData,
211 2 * MAX_PATH);
212
213 VarData->lpCookedValue = GlobalAlloc(GPTR, (_tcslen(lpExpandData) + 1) * sizeof(TCHAR));
214 _tcscpy(VarData->lpCookedValue, lpExpandData);
215 GlobalFree(lpExpandData);
216 }
217
218 memset(&lvi, 0x00, sizeof(lvi));
219 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
220 lvi.lParam = (LPARAM)VarData;
221 lvi.pszText = VarData->lpName;
222 lvi.state = (i == 0) ? LVIS_SELECTED : 0;
223 iItem = ListView_InsertItem(hwndListView, &lvi);
224
225 ListView_SetItemText(hwndListView, iItem, 1,
226 (VarData->lpCookedValue) ? VarData->lpCookedValue : VarData->lpRawValue);
227 }
228
229 GlobalFree(lpName);
230 GlobalFree(lpData);
231 RegCloseKey(hKey);
232 }
233
234
235 static VOID
236 SetListViewColumns(HWND hwndListView)
237 {
238 RECT rect;
239 LV_COLUMN column;
240
241 GetClientRect(hwndListView, &rect);
242
243 memset(&column, 0x00, sizeof(column));
244 column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
245 column.fmt=LVCFMT_LEFT;
246 column.cx = (INT)((rect.right - rect.left) * 0.32);
247 column.iSubItem = 0;
248 column.pszText = _T("Variable");
249 (void)ListView_InsertColumn(hwndListView, 0, &column);
250
251 column.cx = (INT)((rect.right - rect.left) * 0.63);
252 column.iSubItem = 1;
253 column.pszText = _T("Value");
254 (void)ListView_InsertColumn(hwndListView, 1, &column);
255 }
256
257
258 static VOID
259 OnInitDialog(HWND hwndDlg)
260 {
261 HWND hwndListView;
262
263 /* Set user environment variables */
264 hwndListView = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_LIST);
265
266 SetListViewColumns(hwndListView);
267
268 SetEnvironmentVariables(hwndListView,
269 HKEY_CURRENT_USER,
270 _T("Environment"));
271
272 (void)ListView_SetColumnWidth(hwndListView,2,LVSCW_AUTOSIZE_USEHEADER);
273 (void)ListView_Update(hwndListView,0);
274
275
276 /* Set system environment variables */
277 hwndListView = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
278
279 SetListViewColumns(hwndListView);
280
281 SetEnvironmentVariables(hwndListView,
282 HKEY_LOCAL_MACHINE,
283 _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"));
284
285 (void)ListView_SetColumnWidth(hwndListView,2,LVSCW_AUTOSIZE_USEHEADER);
286 (void)ListView_Update(hwndListView,0);
287 }
288
289
290 VOID
291 OnNewVariable(HWND hwndDlg,
292 int iDlgItem)
293 {
294 HWND hwndListView;
295 PVARIABLE_DATA VarData;
296 LV_ITEM lvi;
297 int iItem;
298
299 hwndListView = GetDlgItem(hwndDlg, iDlgItem);
300
301 VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA));
302
303 if (!DialogBoxParam(hApplet,
304 MAKEINTRESOURCE(IDD_EDIT_VARIABLE),
305 hwndDlg,
306 (DLGPROC) EditVariableDlgProc,
307 (LPARAM)VarData) > 0)
308 {
309 if (VarData->lpName != NULL)
310 GlobalFree(VarData->lpName);
311
312 if (VarData->lpRawValue != NULL)
313 GlobalFree(VarData->lpRawValue);
314
315 if (VarData->lpCookedValue != NULL)
316 GlobalFree(VarData->lpCookedValue);
317
318 GlobalFree(VarData);
319 }
320
321 memset(&lvi, 0x00, sizeof(lvi));
322 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
323 lvi.lParam = (LPARAM)VarData;
324 lvi.pszText = VarData->lpName;
325 lvi.state = 0;
326 iItem = ListView_InsertItem(hwndListView, &lvi);
327
328 ListView_SetItemText(hwndListView, iItem, 1,
329 (VarData->lpCookedValue) ? VarData->lpCookedValue : VarData->lpRawValue);
330 }
331
332
333 VOID
334 OnEditVariable(HWND hwndDlg,
335 int iDlgItem)
336 {
337 HWND hwndListView;
338 PVARIABLE_DATA VarData;
339 LV_ITEM lvi;
340 int iItem;
341
342 hwndListView = GetDlgItem(hwndDlg, iDlgItem);
343
344 iItem = ListView_GetSelectionMark(hwndListView);
345 if (iItem != -1)
346 {
347 memset(&lvi, 0x00, sizeof(lvi));
348 lvi.mask = LVIF_PARAM;
349 lvi.iItem = iItem;
350
351 if (ListView_GetItem(hwndListView, &lvi))
352 {
353 VarData = (PVARIABLE_DATA)lvi.lParam;
354
355 if (DialogBoxParam(hApplet,
356 MAKEINTRESOURCE(IDD_EDIT_VARIABLE),
357 hwndDlg,
358 (DLGPROC) EditVariableDlgProc,
359 (LPARAM)VarData) > 0)
360 {
361 ListView_SetItemText(hwndListView, iItem, 0, VarData->lpName);
362 ListView_SetItemText(hwndListView, iItem, 1,
363 (VarData->lpCookedValue) ? VarData->lpCookedValue : VarData->lpRawValue);
364 }
365 }
366 }
367 }
368
369
370 VOID
371 OnDeleteVariable(HWND hwndDlg,
372 int iDlgItem)
373 {
374 HWND hwndListView;
375 PVARIABLE_DATA VarData;
376 LV_ITEM lvi;
377 int iItem;
378
379 hwndListView = GetDlgItem(hwndDlg, iDlgItem);
380
381 iItem = ListView_GetSelectionMark(hwndListView);
382 if (iItem != -1)
383 {
384 memset(&lvi, 0x00, sizeof(lvi));
385 lvi.mask = LVIF_PARAM;
386 lvi.iItem = iItem;
387
388 if (ListView_GetItem(hwndListView, &lvi))
389 {
390 VarData = (PVARIABLE_DATA)lvi.lParam;
391 if (VarData != NULL)
392 {
393 if (VarData->lpName != NULL)
394 GlobalFree(VarData->lpName);
395
396 if (VarData->lpRawValue != NULL)
397 GlobalFree(VarData->lpRawValue);
398
399 if (VarData->lpCookedValue != NULL)
400 GlobalFree(VarData->lpCookedValue);
401
402 GlobalFree(VarData);
403 lvi.lParam = 0;
404 }
405 }
406
407 (void)ListView_DeleteItem(hwndListView, iItem);
408 }
409 }
410
411
412 VOID
413 ReleaseListViewItems(HWND hwndDlg,
414 int iDlgItem)
415 {
416 HWND hwndListView;
417 PVARIABLE_DATA VarData;
418 int nItemCount;
419 LV_ITEM lvi;
420 int i;
421
422 hwndListView = GetDlgItem(hwndDlg, iDlgItem);
423
424 memset(&lvi, 0x00, sizeof(lvi));
425
426 nItemCount = ListView_GetItemCount(hwndListView);
427 for (i = 0; i < nItemCount; i++)
428 {
429 lvi.mask = LVIF_PARAM;
430 lvi.iItem = i;
431
432 if (ListView_GetItem(hwndListView, &lvi))
433 {
434 VarData = (PVARIABLE_DATA)lvi.lParam;
435 if (VarData != NULL)
436 {
437 if (VarData->lpName != NULL)
438 GlobalFree(VarData->lpName);
439
440 if (VarData->lpRawValue != NULL)
441 GlobalFree(VarData->lpRawValue);
442
443 if (VarData->lpCookedValue != NULL)
444 GlobalFree(VarData->lpCookedValue);
445
446 GlobalFree(VarData);
447 lvi.lParam = 0;
448 }
449 }
450 }
451 }
452
453 VOID
454 SetAllVars(HWND hwndDlg,
455 INT iDlgItem)
456 {
457 HWND hwndListView;
458 PVARIABLE_DATA VarData;
459 LV_ITEM lvi;
460 INT iItem;
461 HKEY hk;
462 DWORD Type = 0;
463
464 memset(&lvi, 0x00, sizeof(lvi));
465
466 /* Get the handle to the list box with all system vars in it */
467 hwndListView = GetDlgItem(hwndDlg, iDlgItem);
468 /* first item is 0 */
469 iItem = 0;
470 /* set up struct to retreive item */
471 lvi.mask = LVIF_PARAM;
472 lvi.iItem = iItem;
473
474 /* Open or create the key */
475 if (RegCreateKeyEx((iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER),
476 (iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment") : _T("Environment")),
477 0,
478 NULL,
479 REG_OPTION_NON_VOLATILE,
480 KEY_WRITE | KEY_READ,
481 NULL,
482 &hk,
483 NULL))
484 {
485 return;
486 }
487
488 /* loop through all system variables */
489 while(ListView_GetItem(hwndListView, &lvi))
490 {
491 /* Get the data in each item */
492 VarData = (PVARIABLE_DATA)lvi.lParam;
493 if (VarData != NULL)
494 {
495 /* Get the type */
496 RegQueryValueEx(hk,VarData->lpName,NULL,&Type,NULL,NULL);
497
498 /* Set the new value */
499 if (RegSetValueEx(hk,
500 VarData->lpName,
501 0,
502 Type,
503 (LPBYTE) VarData->lpRawValue,
504 (DWORD) (_tcslen(VarData->lpRawValue)* sizeof(TCHAR))+1)) // was _tcsclen. lstrlen?
505 {
506 RegCloseKey(hk);
507 return;
508 }
509 }
510 /* Fill struct for next item */
511 lvi.mask = LVIF_PARAM;
512 lvi.iItem = ++iItem;
513 }
514
515 RegCloseKey(hk);
516 }
517
518 /* Environment dialog procedure */
519 INT_PTR CALLBACK
520 EnvironmentDlgProc(HWND hwndDlg,
521 UINT uMsg,
522 WPARAM wParam,
523 LPARAM lParam)
524 {
525 switch (uMsg)
526 {
527 case WM_INITDIALOG:
528 OnInitDialog(hwndDlg);
529 break;
530
531 case WM_COMMAND:
532 switch (LOWORD(wParam))
533 {
534 case IDC_USER_VARIABLE_NEW:
535 OnNewVariable(hwndDlg, IDC_USER_VARIABLE_LIST);
536 return TRUE;
537
538 case IDC_USER_VARIABLE_EDIT:
539 OnEditVariable(hwndDlg, IDC_USER_VARIABLE_LIST);
540 return TRUE;
541
542 case IDC_USER_VARIABLE_DELETE:
543 OnDeleteVariable(hwndDlg, IDC_USER_VARIABLE_LIST);
544 return TRUE;
545
546 case IDC_SYSTEM_VARIABLE_NEW:
547 OnNewVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
548 return TRUE;
549
550 case IDC_SYSTEM_VARIABLE_EDIT:
551 OnEditVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
552 return TRUE;
553
554 case IDC_SYSTEM_VARIABLE_DELETE:
555 OnDeleteVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
556 return TRUE;
557
558 case IDOK:
559 SetAllVars(hwndDlg, IDC_USER_VARIABLE_LIST);
560 SetAllVars(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
561
562 case IDCANCEL:
563 ReleaseListViewItems(hwndDlg, IDC_USER_VARIABLE_LIST);
564 ReleaseListViewItems(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
565 EndDialog(hwndDlg, 0);
566 return TRUE;
567 }
568 break;
569
570 case WM_NOTIFY:
571 {
572 NMHDR *phdr;
573
574 phdr = (NMHDR*)lParam;
575 switch(phdr->code)
576 {
577 case NM_DBLCLK:
578 {
579 if (phdr->idFrom == IDC_USER_VARIABLE_LIST ||
580 phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST)
581 {
582 OnEditVariable(hwndDlg, (INT)phdr->idFrom);
583 return TRUE;
584 }
585 }
586 }
587 }
588 break;
589 }
590
591 return FALSE;
592 }
593
594 /* EOF */