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