translate hardcoded strings into 'edit variable' box
[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 TCHAR szStr[32];
241
242 GetClientRect(hwndListView, &rect);
243
244 memset(&column, 0x00, sizeof(column));
245 column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
246 column.fmt=LVCFMT_LEFT;
247 column.cx = (INT)((rect.right - rect.left) * 0.32);
248 column.iSubItem = 0;
249 LoadString(hApplet, IDS_VARIABLE, szStr, sizeof(szStr) / sizeof(szStr[0]));
250 column.pszText = szStr;
251 (void)ListView_InsertColumn(hwndListView, 0, &column);
252
253 column.cx = (INT)((rect.right - rect.left) * 0.63);
254 column.iSubItem = 1;
255 LoadString(hApplet, IDS_VALUE, szStr, sizeof(szStr) / sizeof(szStr[0]));
256 column.pszText = szStr;
257 (void)ListView_InsertColumn(hwndListView, 1, &column);
258 }
259
260
261 static VOID
262 OnInitDialog(HWND hwndDlg)
263 {
264 HWND hwndListView;
265
266 /* Set user environment variables */
267 hwndListView = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_LIST);
268
269 SetListViewColumns(hwndListView);
270
271 SetEnvironmentVariables(hwndListView,
272 HKEY_CURRENT_USER,
273 _T("Environment"));
274
275 (void)ListView_SetColumnWidth(hwndListView,2,LVSCW_AUTOSIZE_USEHEADER);
276 (void)ListView_Update(hwndListView,0);
277
278
279 /* Set system environment variables */
280 hwndListView = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
281
282 SetListViewColumns(hwndListView);
283
284 SetEnvironmentVariables(hwndListView,
285 HKEY_LOCAL_MACHINE,
286 _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"));
287
288 (void)ListView_SetColumnWidth(hwndListView,2,LVSCW_AUTOSIZE_USEHEADER);
289 (void)ListView_Update(hwndListView,0);
290 }
291
292
293 VOID
294 OnNewVariable(HWND hwndDlg,
295 int iDlgItem)
296 {
297 HWND hwndListView;
298 PVARIABLE_DATA VarData;
299 LV_ITEM lvi;
300 int iItem;
301
302 hwndListView = GetDlgItem(hwndDlg, iDlgItem);
303
304 VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA));
305
306 if (!DialogBoxParam(hApplet,
307 MAKEINTRESOURCE(IDD_EDIT_VARIABLE),
308 hwndDlg,
309 (DLGPROC) EditVariableDlgProc,
310 (LPARAM)VarData) > 0)
311 {
312 if (VarData->lpName != NULL)
313 GlobalFree(VarData->lpName);
314
315 if (VarData->lpRawValue != NULL)
316 GlobalFree(VarData->lpRawValue);
317
318 if (VarData->lpCookedValue != NULL)
319 GlobalFree(VarData->lpCookedValue);
320
321 GlobalFree(VarData);
322 }
323
324 memset(&lvi, 0x00, sizeof(lvi));
325 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
326 lvi.lParam = (LPARAM)VarData;
327 lvi.pszText = VarData->lpName;
328 lvi.state = 0;
329 iItem = ListView_InsertItem(hwndListView, &lvi);
330
331 ListView_SetItemText(hwndListView, iItem, 1,
332 (VarData->lpCookedValue) ? VarData->lpCookedValue : VarData->lpRawValue);
333 }
334
335
336 VOID
337 OnEditVariable(HWND hwndDlg,
338 int iDlgItem)
339 {
340 HWND hwndListView;
341 PVARIABLE_DATA VarData;
342 LV_ITEM lvi;
343 int iItem;
344
345 hwndListView = GetDlgItem(hwndDlg, iDlgItem);
346
347 iItem = ListView_GetSelectionMark(hwndListView);
348 if (iItem != -1)
349 {
350 memset(&lvi, 0x00, sizeof(lvi));
351 lvi.mask = LVIF_PARAM;
352 lvi.iItem = iItem;
353
354 if (ListView_GetItem(hwndListView, &lvi))
355 {
356 VarData = (PVARIABLE_DATA)lvi.lParam;
357
358 if (DialogBoxParam(hApplet,
359 MAKEINTRESOURCE(IDD_EDIT_VARIABLE),
360 hwndDlg,
361 (DLGPROC) EditVariableDlgProc,
362 (LPARAM)VarData) > 0)
363 {
364 ListView_SetItemText(hwndListView, iItem, 0, VarData->lpName);
365 ListView_SetItemText(hwndListView, iItem, 1,
366 (VarData->lpCookedValue) ? VarData->lpCookedValue : VarData->lpRawValue);
367 }
368 }
369 }
370 }
371
372
373 VOID
374 OnDeleteVariable(HWND hwndDlg,
375 int iDlgItem)
376 {
377 HWND hwndListView;
378 PVARIABLE_DATA VarData;
379 LV_ITEM lvi;
380 int iItem;
381
382 hwndListView = GetDlgItem(hwndDlg, iDlgItem);
383
384 iItem = ListView_GetSelectionMark(hwndListView);
385 if (iItem != -1)
386 {
387 memset(&lvi, 0x00, sizeof(lvi));
388 lvi.mask = LVIF_PARAM;
389 lvi.iItem = iItem;
390
391 if (ListView_GetItem(hwndListView, &lvi))
392 {
393 VarData = (PVARIABLE_DATA)lvi.lParam;
394 if (VarData != NULL)
395 {
396 if (VarData->lpName != NULL)
397 GlobalFree(VarData->lpName);
398
399 if (VarData->lpRawValue != NULL)
400 GlobalFree(VarData->lpRawValue);
401
402 if (VarData->lpCookedValue != NULL)
403 GlobalFree(VarData->lpCookedValue);
404
405 GlobalFree(VarData);
406 lvi.lParam = 0;
407 }
408 }
409
410 (void)ListView_DeleteItem(hwndListView, iItem);
411 }
412 }
413
414
415 VOID
416 ReleaseListViewItems(HWND hwndDlg,
417 int iDlgItem)
418 {
419 HWND hwndListView;
420 PVARIABLE_DATA VarData;
421 int nItemCount;
422 LV_ITEM lvi;
423 int i;
424
425 hwndListView = GetDlgItem(hwndDlg, iDlgItem);
426
427 memset(&lvi, 0x00, sizeof(lvi));
428
429 nItemCount = ListView_GetItemCount(hwndListView);
430 for (i = 0; i < nItemCount; i++)
431 {
432 lvi.mask = LVIF_PARAM;
433 lvi.iItem = i;
434
435 if (ListView_GetItem(hwndListView, &lvi))
436 {
437 VarData = (PVARIABLE_DATA)lvi.lParam;
438 if (VarData != NULL)
439 {
440 if (VarData->lpName != NULL)
441 GlobalFree(VarData->lpName);
442
443 if (VarData->lpRawValue != NULL)
444 GlobalFree(VarData->lpRawValue);
445
446 if (VarData->lpCookedValue != NULL)
447 GlobalFree(VarData->lpCookedValue);
448
449 GlobalFree(VarData);
450 lvi.lParam = 0;
451 }
452 }
453 }
454 }
455
456 VOID
457 SetAllVars(HWND hwndDlg,
458 INT iDlgItem)
459 {
460 HWND hwndListView;
461 PVARIABLE_DATA VarData;
462 LV_ITEM lvi;
463 INT iItem;
464 HKEY hk;
465 DWORD Type = 0;
466
467 memset(&lvi, 0x00, sizeof(lvi));
468
469 /* Get the handle to the list box with all system vars in it */
470 hwndListView = GetDlgItem(hwndDlg, iDlgItem);
471 /* first item is 0 */
472 iItem = 0;
473 /* set up struct to retreive item */
474 lvi.mask = LVIF_PARAM;
475 lvi.iItem = iItem;
476
477 /* Open or create the key */
478 if (RegCreateKeyEx((iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER),
479 (iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment") : _T("Environment")),
480 0,
481 NULL,
482 REG_OPTION_NON_VOLATILE,
483 KEY_WRITE | KEY_READ,
484 NULL,
485 &hk,
486 NULL))
487 {
488 return;
489 }
490
491 /* loop through all system variables */
492 while(ListView_GetItem(hwndListView, &lvi))
493 {
494 /* Get the data in each item */
495 VarData = (PVARIABLE_DATA)lvi.lParam;
496 if (VarData != NULL)
497 {
498 /* Get the type */
499 RegQueryValueEx(hk,VarData->lpName,NULL,&Type,NULL,NULL);
500
501 /* Set the new value */
502 if (RegSetValueEx(hk,
503 VarData->lpName,
504 0,
505 Type,
506 (LPBYTE) VarData->lpRawValue,
507 (DWORD) (_tcslen(VarData->lpRawValue)* sizeof(TCHAR))+1)) // was _tcsclen. lstrlen?
508 {
509 RegCloseKey(hk);
510 return;
511 }
512 }
513 /* Fill struct for next item */
514 lvi.mask = LVIF_PARAM;
515 lvi.iItem = ++iItem;
516 }
517
518 RegCloseKey(hk);
519 }
520
521 /* Environment dialog procedure */
522 INT_PTR CALLBACK
523 EnvironmentDlgProc(HWND hwndDlg,
524 UINT uMsg,
525 WPARAM wParam,
526 LPARAM lParam)
527 {
528 switch (uMsg)
529 {
530 case WM_INITDIALOG:
531 OnInitDialog(hwndDlg);
532 break;
533
534 case WM_COMMAND:
535 switch (LOWORD(wParam))
536 {
537 case IDC_USER_VARIABLE_NEW:
538 OnNewVariable(hwndDlg, IDC_USER_VARIABLE_LIST);
539 return TRUE;
540
541 case IDC_USER_VARIABLE_EDIT:
542 OnEditVariable(hwndDlg, IDC_USER_VARIABLE_LIST);
543 return TRUE;
544
545 case IDC_USER_VARIABLE_DELETE:
546 OnDeleteVariable(hwndDlg, IDC_USER_VARIABLE_LIST);
547 return TRUE;
548
549 case IDC_SYSTEM_VARIABLE_NEW:
550 OnNewVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
551 return TRUE;
552
553 case IDC_SYSTEM_VARIABLE_EDIT:
554 OnEditVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
555 return TRUE;
556
557 case IDC_SYSTEM_VARIABLE_DELETE:
558 OnDeleteVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
559 return TRUE;
560
561 case IDOK:
562 SetAllVars(hwndDlg, IDC_USER_VARIABLE_LIST);
563 SetAllVars(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
564
565 case IDCANCEL:
566 ReleaseListViewItems(hwndDlg, IDC_USER_VARIABLE_LIST);
567 ReleaseListViewItems(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
568 EndDialog(hwndDlg, 0);
569 return TRUE;
570 }
571 break;
572
573 case WM_NOTIFY:
574 {
575 NMHDR *phdr;
576
577 phdr = (NMHDR*)lParam;
578 switch(phdr->code)
579 {
580 case NM_DBLCLK:
581 {
582 if (phdr->idFrom == IDC_USER_VARIABLE_LIST ||
583 phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST)
584 {
585 OnEditVariable(hwndDlg, (INT)phdr->idFrom);
586 return TRUE;
587 }
588 }
589 }
590 }
591 break;
592 }
593
594 return FALSE;
595 }
596
597 /* EOF */