xref: /reactos/dll/cpl/sysdm/environment.c (revision 2196a06f)
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 typedef struct _VARIABLE_DATA
13 {
14     DWORD dwType;
15     LPTSTR lpName;
16     LPTSTR lpRawValue;
17     LPTSTR lpCookedValue;
18 } VARIABLE_DATA, *PVARIABLE_DATA;
19 
20 
21 static INT
22 GetSelectedListViewItem(HWND hwndListView)
23 {
24     INT iCount;
25     INT iItem;
26 
27     iCount = SendMessage(hwndListView,
28                          LVM_GETITEMCOUNT,
29                          0,
30                          0);
31     if (iCount != LB_ERR)
32     {
33         for (iItem = 0; iItem < iCount; iItem++)
34         {
35             if (SendMessage(hwndListView,
36                             LVM_GETITEMSTATE,
37                             iItem,
38                             (LPARAM) LVIS_SELECTED) == LVIS_SELECTED)
39             {
40                 return iItem;
41             }
42         }
43     }
44 
45     return -1;
46 }
47 
48 
49 static INT_PTR CALLBACK
50 EditVariableDlgProc(HWND hwndDlg,
51                     UINT uMsg,
52                     WPARAM wParam,
53                     LPARAM lParam)
54 {
55     PVARIABLE_DATA VarData;
56     DWORD dwNameLength;
57     DWORD dwValueLength;
58 
59     VarData = (PVARIABLE_DATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
60 
61     switch (uMsg)
62     {
63         case WM_INITDIALOG:
64             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
65             VarData = (PVARIABLE_DATA)lParam;
66 
67             if (VarData->lpName != NULL)
68             {
69                 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_SETTEXT, 0, (LPARAM)VarData->lpName);
70             }
71 
72             if (VarData->lpRawValue != NULL)
73             {
74                 SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_SETTEXT, 0, (LPARAM)VarData->lpRawValue);
75             }
76             break;
77 
78         case WM_COMMAND:
79             switch (LOWORD(wParam))
80             {
81                 case IDOK:
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)
85                     {
86                         LPTSTR p;
87 
88                         if (VarData->lpName == NULL)
89                         {
90                             VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR));
91                         }
92                         else if (_tcslen(VarData->lpName) < dwNameLength)
93                         {
94                             GlobalFree(VarData->lpName);
95                             VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR));
96                         }
97                         SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_GETTEXT, dwNameLength + 1, (LPARAM)VarData->lpName);
98 
99                         if (VarData->lpRawValue == NULL)
100                         {
101                             VarData->lpRawValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR));
102                         }
103                         else if (_tcslen(VarData->lpRawValue) < dwValueLength)
104                         {
105                             GlobalFree(VarData->lpRawValue);
106                             VarData->lpRawValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR));
107                         }
108                         SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_GETTEXT, dwValueLength + 1, (LPARAM)VarData->lpRawValue);
109 
110                         if (VarData->lpCookedValue != NULL)
111                         {
112                             GlobalFree(VarData->lpCookedValue);
113                             VarData->lpCookedValue = NULL;
114                         }
115 
116                         p = _tcschr(VarData->lpRawValue, _T('%'));
117                         if (p && _tcschr(++p, _T('%')))
118                         {
119                             VarData->dwType = REG_EXPAND_SZ;
120                             VarData->lpCookedValue = GlobalAlloc(GPTR, 2 * MAX_PATH * sizeof(TCHAR));
121 
122                             ExpandEnvironmentStrings(VarData->lpRawValue,
123                                                      VarData->lpCookedValue,
124                                                      2 * MAX_PATH);
125                         }
126                         else
127                         {
128                             VarData->dwType = REG_SZ;
129                             VarData->lpCookedValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR));
130                             _tcscpy(VarData->lpCookedValue, VarData->lpRawValue);
131                         }
132                     }
133                     EndDialog(hwndDlg, 1);
134                     return TRUE;
135 
136                 case IDCANCEL:
137                     EndDialog(hwndDlg, 0);
138                     return TRUE;
139             }
140             break;
141     }
142 
143     return FALSE;
144 }
145 
146 
147 static VOID
148 GetEnvironmentVariables(HWND hwndListView,
149                         HKEY hRootKey,
150                         LPTSTR lpSubKeyName)
151 {
152     HKEY hKey;
153     DWORD dwValues;
154     DWORD dwMaxValueNameLength;
155     DWORD dwMaxValueDataLength;
156     DWORD i;
157     LPTSTR lpName;
158     LPTSTR lpData;
159     LPTSTR lpExpandData;
160     DWORD dwNameLength;
161     DWORD dwDataLength;
162     DWORD dwType;
163     PVARIABLE_DATA VarData;
164 
165     LV_ITEM lvi;
166     int iItem;
167 
168     if (RegOpenKeyEx(hRootKey,
169                      lpSubKeyName,
170                      0,
171                      KEY_READ,
172                      &hKey))
173         return;
174 
175     if (RegQueryInfoKey(hKey,
176                         NULL,
177                         NULL,
178                         NULL,
179                         NULL,
180                         NULL,
181                         NULL,
182                         &dwValues,
183                         &dwMaxValueNameLength,
184                         &dwMaxValueDataLength,
185                         NULL,
186                         NULL))
187     {
188         RegCloseKey(hKey);
189         return;
190     }
191 
192     lpName = GlobalAlloc(GPTR, (dwMaxValueNameLength + 1) * sizeof(TCHAR));
193     if (lpName == NULL)
194     {
195         RegCloseKey(hKey);
196         return;
197     }
198 
199     lpData = GlobalAlloc(GPTR, (dwMaxValueDataLength + 1) * sizeof(TCHAR));
200     if (lpData == NULL)
201     {
202         GlobalFree(lpName);
203         RegCloseKey(hKey);
204         return;
205     }
206 
207     lpExpandData = GlobalAlloc(GPTR, 2048 * sizeof(TCHAR));
208     if (lpExpandData == NULL)
209     {
210         GlobalFree(lpName);
211         GlobalFree(lpData);
212         RegCloseKey(hKey);
213         return;
214     }
215 
216     for (i = 0; i < dwValues; i++)
217     {
218         dwNameLength = dwMaxValueNameLength + 1;
219         dwDataLength = dwMaxValueDataLength + 1;
220 
221         if (RegEnumValue(hKey,
222                          i,
223                          lpName,
224                          &dwNameLength,
225                          NULL,
226                          &dwType,
227                          (LPBYTE)lpData,
228                          &dwDataLength))
229         {
230             GlobalFree(lpExpandData);
231             GlobalFree(lpName);
232             GlobalFree(lpData);
233             RegCloseKey(hKey);
234             return;
235         }
236 
237         if (dwType != REG_SZ && dwType != REG_EXPAND_SZ)
238             continue;
239 
240         VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA));
241 
242         VarData->dwType = dwType;
243 
244         VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR));
245         _tcscpy(VarData->lpName, lpName);
246 
247         VarData->lpRawValue = GlobalAlloc(GPTR, (dwDataLength + 1) * sizeof(TCHAR));
248         _tcscpy(VarData->lpRawValue, lpData);
249 
250         ExpandEnvironmentStrings(lpData, lpExpandData, 2048);
251 
252         VarData->lpCookedValue = GlobalAlloc(GPTR, (_tcslen(lpExpandData) + 1) * sizeof(TCHAR));
253         _tcscpy(VarData->lpCookedValue, lpExpandData);
254 
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);
261 
262         ListView_SetItemText(hwndListView, iItem, 1, VarData->lpCookedValue);
263     }
264 
265     GlobalFree(lpExpandData);
266     GlobalFree(lpName);
267     GlobalFree(lpData);
268     RegCloseKey(hKey);
269 }
270 
271 
272 static VOID
273 SetEnvironmentDialogListViewColumns(HWND hwndListView)
274 {
275     RECT rect;
276     LV_COLUMN column;
277     TCHAR szStr[32];
278 
279     GetClientRect(hwndListView, &rect);
280 
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);
285     column.iSubItem = 0;
286     LoadString(hApplet, IDS_VARIABLE, szStr, sizeof(szStr) / sizeof(szStr[0]));
287     column.pszText = szStr;
288     (void)ListView_InsertColumn(hwndListView, 0, &column);
289 
290     column.cx = (INT)((rect.right - rect.left) * 0.63);
291     column.iSubItem = 1;
292     LoadString(hApplet, IDS_VALUE, szStr, sizeof(szStr) / sizeof(szStr[0]));
293     column.pszText = szStr;
294     (void)ListView_InsertColumn(hwndListView, 1, &column);
295 }
296 
297 
298 static VOID
299 OnInitEnvironmentDialog(HWND hwndDlg)
300 {
301     HWND hwndListView;
302 
303     /* Set user environment variables */
304     hwndListView = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_LIST);
305 
306     (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT);
307 
308     SetEnvironmentDialogListViewColumns(hwndListView);
309 
310     GetEnvironmentVariables(hwndListView,
311                             HKEY_CURRENT_USER,
312                             _T("Environment"));
313 
314     (void)ListView_SetColumnWidth(hwndListView, 2, LVSCW_AUTOSIZE_USEHEADER);
315 
316     ListView_SetItemState(hwndListView, 0,
317                           LVIS_FOCUSED | LVIS_SELECTED,
318                           LVIS_FOCUSED | LVIS_SELECTED);
319 
320     (void)ListView_Update(hwndListView,0);
321 
322     /* Set system environment variables */
323     hwndListView = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
324 
325     (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT);
326 
327     SetEnvironmentDialogListViewColumns(hwndListView);
328 
329     GetEnvironmentVariables(hwndListView,
330                             HKEY_LOCAL_MACHINE,
331                             _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"));
332 
333     (void)ListView_SetColumnWidth(hwndListView, 2, LVSCW_AUTOSIZE_USEHEADER);
334 
335     ListView_SetItemState(hwndListView, 0,
336                           LVIS_FOCUSED | LVIS_SELECTED,
337                           LVIS_FOCUSED | LVIS_SELECTED);
338 
339     (void)ListView_Update(hwndListView, 0);
340 }
341 
342 
343 static VOID
344 OnNewVariable(HWND hwndDlg,
345               INT iDlgItem)
346 {
347     HWND hwndListView;
348     PVARIABLE_DATA VarData;
349     LV_ITEM lvi;
350     INT iItem;
351 
352     hwndListView = GetDlgItem(hwndDlg, iDlgItem);
353 
354     VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA));
355 
356     if (DialogBoxParam(hApplet,
357                        MAKEINTRESOURCE(IDD_EDIT_VARIABLE),
358                        hwndDlg,
359                        EditVariableDlgProc,
360                        (LPARAM)VarData) <= 0)
361     {
362         if (VarData->lpName != NULL)
363             GlobalFree(VarData->lpName);
364 
365         if (VarData->lpRawValue != NULL)
366             GlobalFree(VarData->lpRawValue);
367 
368         if (VarData->lpCookedValue != NULL)
369             GlobalFree(VarData->lpCookedValue);
370 
371         GlobalFree(VarData);
372     }
373     else
374     {
375         if (VarData->lpName != NULL && (VarData->lpCookedValue || VarData->lpRawValue))
376         {
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;
381             lvi.state = 0;
382             iItem = ListView_InsertItem(hwndListView, &lvi);
383 
384             ListView_SetItemText(hwndListView, iItem, 1, VarData->lpCookedValue);
385         }
386     }
387 }
388 
389 
390 static VOID
391 OnEditVariable(HWND hwndDlg,
392                INT iDlgItem)
393 {
394     HWND hwndListView;
395     PVARIABLE_DATA VarData;
396     LV_ITEM lvi;
397     INT iItem;
398 
399     hwndListView = GetDlgItem(hwndDlg, iDlgItem);
400 
401     iItem = GetSelectedListViewItem(hwndListView);
402     if (iItem != -1)
403     {
404         memset(&lvi, 0x00, sizeof(lvi));
405         lvi.mask = LVIF_PARAM;
406         lvi.iItem = iItem;
407 
408         if (ListView_GetItem(hwndListView, &lvi))
409         {
410             VarData = (PVARIABLE_DATA)lvi.lParam;
411 
412             if (DialogBoxParam(hApplet,
413                                MAKEINTRESOURCE(IDD_EDIT_VARIABLE),
414                                hwndDlg,
415                                EditVariableDlgProc,
416                                (LPARAM)VarData) > 0)
417             {
418                 ListView_SetItemText(hwndListView, iItem, 0, VarData->lpName);
419                 ListView_SetItemText(hwndListView, iItem, 1, VarData->lpCookedValue);
420             }
421         }
422     }
423 }
424 
425 
426 static VOID
427 OnDeleteVariable(HWND hwndDlg,
428                  INT iDlgItem)
429 {
430     HWND hwndListView;
431     PVARIABLE_DATA VarData;
432     LV_ITEM lvi;
433     INT iItem;
434 
435     hwndListView = GetDlgItem(hwndDlg, iDlgItem);
436 
437     iItem = GetSelectedListViewItem(hwndListView);
438     if (iItem != -1)
439     {
440         memset(&lvi, 0x00, sizeof(lvi));
441         lvi.mask = LVIF_PARAM;
442         lvi.iItem = iItem;
443 
444         if (ListView_GetItem(hwndListView, &lvi))
445         {
446             VarData = (PVARIABLE_DATA)lvi.lParam;
447             if (VarData != NULL)
448             {
449                 if (VarData->lpName != NULL)
450                     GlobalFree(VarData->lpName);
451 
452                 if (VarData->lpRawValue != NULL)
453                     GlobalFree(VarData->lpRawValue);
454 
455                 if (VarData->lpCookedValue != NULL)
456                     GlobalFree(VarData->lpCookedValue);
457 
458                 GlobalFree(VarData);
459                 lvi.lParam = 0;
460             }
461         }
462 
463         (void)ListView_DeleteItem(hwndListView, iItem);
464 
465         /* Select the previous item */
466         if (iItem > 0)
467             iItem--;
468 
469         ListView_SetItemState(hwndListView, iItem,
470                               LVIS_FOCUSED | LVIS_SELECTED,
471                               LVIS_FOCUSED | LVIS_SELECTED);
472     }
473 }
474 
475 
476 static VOID
477 ReleaseListViewItems(HWND hwndDlg,
478                      INT iDlgItem)
479 {
480     HWND hwndListView;
481     PVARIABLE_DATA VarData;
482     LV_ITEM lvi;
483     INT nItemCount;
484     INT i;
485 
486     hwndListView = GetDlgItem(hwndDlg, iDlgItem);
487 
488     memset(&lvi, 0x00, sizeof(lvi));
489 
490     nItemCount = ListView_GetItemCount(hwndListView);
491     for (i = 0; i < nItemCount; i++)
492     {
493         lvi.mask = LVIF_PARAM;
494         lvi.iItem = i;
495 
496         if (ListView_GetItem(hwndListView, &lvi))
497         {
498             VarData = (PVARIABLE_DATA)lvi.lParam;
499             if (VarData != NULL)
500             {
501                 if (VarData->lpName != NULL)
502                     GlobalFree(VarData->lpName);
503 
504                 if (VarData->lpRawValue != NULL)
505                     GlobalFree(VarData->lpRawValue);
506 
507                 if (VarData->lpCookedValue != NULL)
508                     GlobalFree(VarData->lpCookedValue);
509 
510                 GlobalFree(VarData);
511                 lvi.lParam = 0;
512             }
513         }
514     }
515 }
516 
517 
518 static VOID
519 SetAllVars(HWND hwndDlg,
520            INT iDlgItem)
521 {
522     HWND hwndListView;
523     PVARIABLE_DATA VarData;
524     LV_ITEM lvi;
525     INT iItem;
526     HKEY hKey;
527     DWORD dwValueCount;
528     DWORD dwMaxValueNameLength;
529     LPTSTR *aValueArray;
530     DWORD dwNameLength;
531     DWORD i;
532     TCHAR szBuffer[256];
533     LPTSTR lpBuffer;
534 
535     memset(&lvi, 0x00, sizeof(lvi));
536 
537     /* Get the handle to the list box with all system vars in it */
538     hwndListView = GetDlgItem(hwndDlg, iDlgItem);
539     /* First item is 0 */
540     iItem = 0;
541     /* Set up struct to retrieve item */
542     lvi.mask = LVIF_PARAM;
543     lvi.iItem = iItem;
544 
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")),
548                        0,
549                        NULL,
550                        REG_OPTION_NON_VOLATILE,
551                        KEY_WRITE | KEY_READ,
552                        NULL,
553                        &hKey,
554                        NULL))
555     {
556         return;
557     }
558 
559     /* Get the number of values and the maximum value name length */
560     if (RegQueryInfoKey(hKey,
561                         NULL,
562                         NULL,
563                         NULL,
564                         NULL,
565                         NULL,
566                         NULL,
567                         &dwValueCount,
568                         &dwMaxValueNameLength,
569                         NULL,
570                         NULL,
571                         NULL))
572     {
573         RegCloseKey(hKey);
574         return;
575     }
576 
577     if (dwValueCount > 0)
578     {
579         /* Allocate the value array */
580         aValueArray = GlobalAlloc(GPTR, dwValueCount * sizeof(LPTSTR));
581         if (aValueArray != NULL)
582         {
583             /* Get all value names */
584             for (i = 0; i < dwValueCount; i++)
585             {
586                 dwNameLength = 256;
587                 if (!RegEnumValue(hKey,
588                                   i,
589                                   szBuffer,
590                                   &dwNameLength,
591                                   NULL,
592                                   NULL,
593                                   NULL,
594                                   NULL))
595                 {
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)
599                     {
600                         _tcscpy(lpBuffer, szBuffer);
601                         aValueArray[i] = lpBuffer;
602                     }
603                 }
604             }
605 
606             /* Delete all values */
607             for (i = 0; i < dwValueCount; i++)
608             {
609                 if (aValueArray[i] != NULL)
610                 {
611                     /* Delete the value */
612                     RegDeleteValue(hKey,
613                                    aValueArray[i]);
614 
615                     /* Free the value name */
616                     GlobalFree(aValueArray[i]);
617                 }
618             }
619 
620             /* Free the value array */
621             GlobalFree(aValueArray);
622         }
623     }
624 
625     /* Loop through all variables */
626     while (ListView_GetItem(hwndListView, &lvi))
627     {
628         /* Get the data in each item */
629         VarData = (PVARIABLE_DATA)lvi.lParam;
630         if (VarData != NULL)
631         {
632             /* Set the new value */
633             if (RegSetValueEx(hKey,
634                               VarData->lpName,
635                               0,
636                               VarData->dwType,
637                               (LPBYTE)VarData->lpRawValue,
638                               (DWORD)(_tcslen(VarData->lpRawValue) + 1) * sizeof(TCHAR)))
639             {
640                 RegCloseKey(hKey);
641                 return;
642             }
643         }
644 
645         /* Fill struct for next item */
646         lvi.mask = LVIF_PARAM;
647         lvi.iItem = ++iItem;
648     }
649 
650     RegCloseKey(hKey);
651 }
652 
653 
654 static BOOL
655 OnNotify(HWND hwndDlg, NMHDR *phdr)
656 {
657     switch(phdr->code)
658     {
659         case NM_DBLCLK:
660             if (phdr->idFrom == IDC_USER_VARIABLE_LIST ||
661                 phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST)
662             {
663                 OnEditVariable(hwndDlg, (INT)phdr->idFrom);
664                 return TRUE;
665             }
666             break;
667 
668         case LVN_KEYDOWN:
669             if (((LPNMLVKEYDOWN)phdr)->wVKey == VK_DELETE &&
670                 (phdr->idFrom == IDC_USER_VARIABLE_LIST ||
671                  phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST))
672             {
673                 OnDeleteVariable(hwndDlg, (INT)phdr->idFrom);
674                 return TRUE;
675             }
676             break;
677     }
678 
679     return FALSE;
680 }
681 
682 
683 /* Environment dialog procedure */
684 INT_PTR CALLBACK
685 EnvironmentDlgProc(HWND hwndDlg,
686                    UINT uMsg,
687                    WPARAM wParam,
688                    LPARAM lParam)
689 {
690     switch (uMsg)
691     {
692         case WM_INITDIALOG:
693             OnInitEnvironmentDialog(hwndDlg);
694             break;
695 
696         case WM_COMMAND:
697             switch (LOWORD(wParam))
698             {
699                 case IDC_USER_VARIABLE_NEW:
700                     OnNewVariable(hwndDlg, IDC_USER_VARIABLE_LIST);
701                     return TRUE;
702 
703                 case IDC_USER_VARIABLE_EDIT:
704                     OnEditVariable(hwndDlg, IDC_USER_VARIABLE_LIST);
705                     return TRUE;
706 
707                 case IDC_USER_VARIABLE_DELETE:
708                     OnDeleteVariable(hwndDlg, IDC_USER_VARIABLE_LIST);
709                     return TRUE;
710 
711                 case IDC_SYSTEM_VARIABLE_NEW:
712                     OnNewVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
713                     return TRUE;
714 
715                 case IDC_SYSTEM_VARIABLE_EDIT:
716                     OnEditVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
717                     return TRUE;
718 
719                 case IDC_SYSTEM_VARIABLE_DELETE:
720                     OnDeleteVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
721                     return TRUE;
722 
723                 case IDOK:
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);
729                     return TRUE;
730 
731                 case IDCANCEL:
732                     EndDialog(hwndDlg, 0);
733                     return TRUE;
734             }
735             break;
736 
737         case WM_DESTROY:
738             ReleaseListViewItems(hwndDlg, IDC_USER_VARIABLE_LIST);
739             ReleaseListViewItems(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
740             break;
741 
742         case WM_NOTIFY:
743             return OnNotify(hwndDlg, (NMHDR*)lParam);
744     }
745 
746     return FALSE;
747 }
748 
749 /* EOF */
750