xref: /reactos/dll/cpl/sysdm/environment.c (revision a8e06d92)
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  *              Copyright 2021 Arnav Bhatt <arnavbhatt288@gmail.com>
8  */
9 
10 #include "precomp.h"
11 #include <commctrl.h>
12 #include <commdlg.h>
13 #include <string.h>
14 
15 typedef struct _VARIABLE_DATA
16 {
17     DWORD dwType;
18     LPTSTR lpName;
19     LPTSTR lpRawValue;
20     LPTSTR lpCookedValue;
21 } VARIABLE_DATA, *PVARIABLE_DATA;
22 
23 typedef struct _ENVIRONMENT_DIALOG_DATA
24 {
25     DWORD cxMin;
26     DWORD cyMin;
27     DWORD cxOld;
28     DWORD cyOld;
29 } ENVIRONMENT_DIALOG_DATA, *PENVIRONMENT_DIALOG_DATA;
30 
31 typedef struct _ENVIRONMENT_EDIT_DIALOG_DATA
32 {
33     BOOL bIsItemSelected;
34     DWORD dwSelectedValueIndex;
35     DWORD cxMin;
36     DWORD cyMin;
37     DWORD cxOld;
38     DWORD cyOld;
39     DWORD dwDlgID;
40     HWND hEditBox;
41     PVARIABLE_DATA VarData;
42 } EDIT_DIALOG_DATA, *PEDIT_DIALOG_DATA;
43 
44 static BOOL
DetermineDialogBoxType(LPTSTR lpRawValue)45 DetermineDialogBoxType(LPTSTR lpRawValue)
46 {
47     DWORD dwValueLength;
48     LPTSTR lpTemp;
49     LPTSTR lpToken;
50 
51     dwValueLength = _tcslen(lpRawValue) + 1;
52     lpTemp = GlobalAlloc(GPTR, dwValueLength * sizeof(TCHAR));
53     if (!lpTemp)
54         return FALSE;
55 
56     StringCchCopy(lpTemp, dwValueLength, lpRawValue);
57 
58     for (lpToken = _tcstok(lpTemp, _T(";"));
59          lpToken != NULL;
60          lpToken = _tcstok(NULL, _T(";")))
61     {
62         /* If the string has environment variable then expand it */
63         ExpandEnvironmentStrings(lpToken, lpToken, dwValueLength);
64 
65         if (!PathIsDirectoryW(lpToken))
66             return FALSE;
67     }
68     GlobalFree(lpTemp);
69 
70     return TRUE;
71 }
72 
73 static DWORD
GatherDataFromEditBox(HWND hwndDlg,PVARIABLE_DATA VarData)74 GatherDataFromEditBox(HWND hwndDlg,
75                       PVARIABLE_DATA VarData)
76 {
77     DWORD dwNameLength;
78     DWORD dwValueLength;
79 
80     dwNameLength = SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_GETTEXTLENGTH, 0, 0);
81     dwValueLength = SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_GETTEXTLENGTH, 0, 0);
82 
83     if (dwNameLength == 0 || dwValueLength == 0)
84     {
85         return 0;
86     }
87 
88     /* Reallocate the name buffer, regrowing it if necessary */
89     if (!VarData->lpName || (_tcslen(VarData->lpName) < dwNameLength))
90     {
91         if (VarData->lpName)
92             GlobalFree(VarData->lpName);
93 
94         VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR));
95         if (!VarData->lpName)
96             return 0;
97     }
98     SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_GETTEXT, dwNameLength + 1, (LPARAM)VarData->lpName);
99 
100     /* Reallocate the value buffer, regrowing it if necessary */
101     if (!VarData->lpRawValue || (_tcslen(VarData->lpRawValue) < dwValueLength))
102     {
103         if (VarData->lpRawValue)
104             GlobalFree(VarData->lpRawValue);
105 
106         VarData->lpRawValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR));
107         if (!VarData->lpRawValue)
108             return 0;
109     }
110     SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_GETTEXT, dwValueLength + 1, (LPARAM)VarData->lpRawValue);
111 
112     return dwValueLength;
113 }
114 
115 static DWORD
GatherDataFromListView(HWND hwndListView,PVARIABLE_DATA VarData)116 GatherDataFromListView(HWND hwndListView,
117                        PVARIABLE_DATA VarData)
118 {
119     DWORD dwValueLength;
120     DWORD NumberOfItems;
121     DWORD i;
122     TCHAR szData[MAX_PATH];
123 
124     /* Gather the number of items for the semi-colon */
125     NumberOfItems = ListView_GetItemCount(hwndListView);
126     if (NumberOfItems == 0)
127     {
128         return 0;
129     }
130 
131     /* Since the last item doesn't need the semi-colon subtract 1 */
132     dwValueLength = NumberOfItems - 1;
133 
134     for (i = 0; i < NumberOfItems; i++)
135     {
136         ListView_GetItemText(hwndListView,
137                              i,
138                              0,
139                              szData,
140                              _countof(szData));
141         dwValueLength += _tcslen(szData);
142     }
143 
144     /* Reallocate the value buffer, regrowing it if necessary */
145     if (!VarData->lpRawValue || (_tcslen(VarData->lpRawValue) < dwValueLength))
146     {
147         if (VarData->lpRawValue)
148             GlobalFree(VarData->lpRawValue);
149 
150         VarData->lpRawValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR));
151         if (!VarData->lpRawValue)
152             return 0;
153     }
154 
155     /* First reinitialize the value buffer, then copy the variable values while
156      * separating them with a semi-colon, except for the last value. */
157     VarData->lpRawValue[0] = _T('\0');
158     for (i = 0; i < NumberOfItems; i++)
159     {
160         if (i > 0)
161         {
162             StringCchCat(VarData->lpRawValue, dwValueLength + 1, _T(";"));
163         }
164         ListView_GetItemText(hwndListView,
165                              i,
166                              0,
167                              szData,
168                              _countof(szData));
169         StringCchCat(VarData->lpRawValue, dwValueLength + 1, szData);
170     }
171     return dwValueLength;
172 }
173 
174 static INT
GetSelectedListViewItem(HWND hwndListView)175 GetSelectedListViewItem(HWND hwndListView)
176 {
177     INT iCount;
178     INT iItem;
179 
180     iCount = SendMessage(hwndListView,
181                          LVM_GETITEMCOUNT,
182                          0,
183                          0);
184     if (iCount != LB_ERR)
185     {
186         for (iItem = 0; iItem < iCount; iItem++)
187         {
188             if (SendMessage(hwndListView,
189                             LVM_GETITEMSTATE,
190                             iItem,
191                             (LPARAM) LVIS_SELECTED) == LVIS_SELECTED)
192             {
193                 return iItem;
194             }
195         }
196     }
197 
198     return -1;
199 }
200 
201 static LRESULT CALLBACK
ListViewSubclassProc(HWND hListBox,UINT uMsg,WPARAM wParam,LPARAM lParam,UINT_PTR uIdSubclass,DWORD_PTR dwRefData)202 ListViewSubclassProc(HWND hListBox,
203                     UINT uMsg,
204                     WPARAM wParam,
205                     LPARAM lParam,
206                     UINT_PTR uIdSubclass,
207                     DWORD_PTR dwRefData)
208 {
209     switch (uMsg)
210     {
211         case WM_DESTROY:
212         {
213             RemoveWindowSubclass(hListBox, ListViewSubclassProc, uIdSubclass);
214             break;
215         }
216 
217         /* Whenever the control is resized make sure it doesn't spawn the horizontal scrollbar */
218         case WM_SIZE:
219         {
220             ShowScrollBar(hListBox, SB_HORZ, FALSE);
221             break;
222         }
223     }
224 
225     return DefSubclassProc(hListBox, uMsg, wParam, lParam);
226 }
227 
228 static VOID
AddEmptyItem(HWND hwndListView,DWORD dwSelectedValueIndex)229 AddEmptyItem(HWND hwndListView,
230              DWORD dwSelectedValueIndex)
231 {
232     LV_ITEM lvi;
233 
234     ZeroMemory(&lvi, sizeof(lvi));
235     lvi.mask = LVIF_TEXT | LVIF_STATE;
236     lvi.cchTextMax = MAX_PATH;
237     lvi.pszText = _T("");
238     lvi.iItem = dwSelectedValueIndex;
239     lvi.iSubItem = 0;
240     ListView_InsertItem(hwndListView, &lvi);
241 }
242 
243 static VOID
AddValuesToList(HWND hwndDlg,PEDIT_DIALOG_DATA DlgData)244 AddValuesToList(HWND hwndDlg,
245                 PEDIT_DIALOG_DATA DlgData)
246 {
247     LV_COLUMN column;
248     LV_ITEM lvi;
249     RECT rItem;
250 
251     DWORD dwValueLength;
252     DWORD i;
253     HWND hwndListView;
254     LPTSTR lpTemp;
255     LPTSTR lpToken;
256 
257     ZeroMemory(&column, sizeof(column));
258     ZeroMemory(&lvi, sizeof(lvi));
259 
260     hwndListView = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE);
261 
262     GetClientRect(hwndListView, &rItem);
263 
264     column.mask = LVCF_WIDTH;
265     column.cx = rItem.right;
266     ListView_InsertColumn(hwndListView, 0, &column);
267     ShowScrollBar(hwndListView, SB_HORZ, FALSE);
268 
269     lvi.mask = LVIF_TEXT | LVIF_STATE;
270     lvi.cchTextMax = MAX_PATH;
271     lvi.iSubItem = 0;
272 
273     dwValueLength = _tcslen(DlgData->VarData->lpRawValue) + 1;
274     lpTemp = GlobalAlloc(GPTR, dwValueLength * sizeof(TCHAR));
275     if (!lpTemp)
276         return;
277 
278     StringCchCopy(lpTemp, dwValueLength, DlgData->VarData->lpRawValue);
279 
280     for (lpToken = _tcstok(lpTemp, _T(";")), i = 0;
281          lpToken != NULL;
282          lpToken = _tcstok(NULL, _T(";")), i++)
283     {
284         lvi.iItem = i;
285         lvi.pszText = lpToken;
286         lvi.state = (i == 0) ? LVIS_SELECTED : 0;
287         ListView_InsertItem(hwndListView, &lvi);
288     }
289 
290     DlgData->dwSelectedValueIndex = 0;
291     ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
292     ListView_SetItemState(hwndListView, DlgData->dwSelectedValueIndex,
293                           LVIS_FOCUSED | LVIS_SELECTED,
294                           LVIS_FOCUSED | LVIS_SELECTED);
295 
296     ListView_Update(hwndListView, DlgData->dwSelectedValueIndex);
297     GlobalFree(lpTemp);
298 }
299 
300 static VOID
BrowseRequiredFile(HWND hwndDlg)301 BrowseRequiredFile(HWND hwndDlg)
302 {
303     OPENFILENAME ofn;
304     TCHAR szFilter[MAX_STR_LENGTH] = _T("");
305     TCHAR szFile[MAX_PATH] = _T("");
306 
307     LoadString(hApplet, IDS_FILE_BROWSE_FILTER, szFilter, _countof(szFilter));
308 
309     ZeroMemory(&ofn, sizeof(ofn));
310 
311     ofn.lStructSize = sizeof(ofn);
312     ofn.hwndOwner = hwndDlg;
313     ofn.lpstrFilter = szFilter;
314     ofn.lpstrFile = szFile;
315     ofn.nMaxFile = _countof(szFile);
316     ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
317 
318     if (GetOpenFileName(&ofn))
319     {
320         SetDlgItemText(hwndDlg, IDC_VARIABLE_VALUE, szFile);
321     }
322 }
323 
324 static VOID
BrowseRequiredFolder(HWND hwndDlg,PEDIT_DIALOG_DATA DlgData)325 BrowseRequiredFolder(HWND hwndDlg,
326                      PEDIT_DIALOG_DATA DlgData)
327 {
328     HWND hwndListView;
329     TCHAR szDir[MAX_PATH];
330 
331     BROWSEINFO bi;
332     LPITEMIDLIST pidllist;
333 
334     ZeroMemory(&bi, sizeof(bi));
335     bi.hwndOwner = hwndDlg;
336     bi.ulFlags = BIF_NEWDIALOGSTYLE;
337 
338     hwndListView = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE);
339 
340     pidllist = SHBrowseForFolder(&bi);
341     if (!pidllist)
342     {
343         return;
344     }
345 
346     if (SHGetPathFromIDList(pidllist, szDir))
347     {
348         if (DlgData->dwDlgID == IDD_EDIT_VARIABLE_FANCY)
349         {
350             /* If no item is selected then create a new empty item and add the required location to it */
351             if (!DlgData->bIsItemSelected)
352             {
353                 DlgData->dwSelectedValueIndex = ListView_GetItemCount(hwndListView);
354                 AddEmptyItem(hwndListView, DlgData->dwSelectedValueIndex);
355             }
356             ListView_SetItemText(hwndListView,
357                                  DlgData->dwSelectedValueIndex,
358                                  0,
359                                  szDir);
360             ListView_SetItemState(hwndListView, DlgData->dwSelectedValueIndex,
361                                   LVIS_FOCUSED | LVIS_SELECTED,
362                                   LVIS_FOCUSED | LVIS_SELECTED);
363         }
364         else
365         {
366             SetDlgItemText(hwndDlg, IDC_VARIABLE_VALUE, szDir);
367         }
368     }
369 
370     CoTaskMemFree(pidllist);
371 }
372 
373 static VOID
MoveListItem(HWND hwndDlg,PEDIT_DIALOG_DATA DlgData,BOOL bMoveUp)374 MoveListItem(HWND hwndDlg,
375              PEDIT_DIALOG_DATA DlgData,
376              BOOL bMoveUp)
377 {
378     TCHAR szDest[MAX_PATH];
379     TCHAR szSource[MAX_PATH];
380     HWND hwndListView;
381     DWORD dwSrcIndex, dwDestIndex, dwLastIndex;
382 
383     hwndListView = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE);
384 
385     dwLastIndex = ListView_GetItemCount(hwndListView) - 1;
386     dwSrcIndex = DlgData->dwSelectedValueIndex;
387     dwDestIndex = bMoveUp ? (dwSrcIndex - 1) : (dwSrcIndex + 1);
388 
389     if ((bMoveUp && dwSrcIndex > 0) || (!bMoveUp && dwSrcIndex < dwLastIndex))
390     {
391         ListView_GetItemText(hwndListView,
392                              dwSrcIndex,
393                              0,
394                              szDest,
395                              _countof(szDest));
396         ListView_GetItemText(hwndListView,
397                              dwDestIndex,
398                              0,
399                              szSource,
400                              _countof(szSource));
401 
402         ListView_SetItemText(hwndListView,
403                              dwDestIndex,
404                              0,
405                              szDest);
406         ListView_SetItemText(hwndListView,
407                              dwSrcIndex,
408                              0,
409                              szSource);
410 
411         DlgData->dwSelectedValueIndex = dwDestIndex;
412         ListView_SetItemState(hwndListView, DlgData->dwSelectedValueIndex,
413                               LVIS_FOCUSED | LVIS_SELECTED,
414                               LVIS_FOCUSED | LVIS_SELECTED);
415     }
416 }
417 
418 static VOID
OnEnvironmentEditDlgResize(HWND hwndDlg,PEDIT_DIALOG_DATA DlgData,DWORD cx,DWORD cy)419 OnEnvironmentEditDlgResize(HWND hwndDlg,
420                            PEDIT_DIALOG_DATA DlgData,
421                            DWORD cx,
422                            DWORD cy)
423 {
424     RECT rect;
425     HDWP hdwp = NULL;
426     HWND hItemWnd;
427 
428     if ((cx == DlgData->cxOld) && (cy == DlgData->cyOld))
429         return;
430 
431     if (DlgData->dwDlgID == IDD_EDIT_VARIABLE)
432     {
433         hdwp = BeginDeferWindowPos(5);
434 
435         /* For the edit control */
436         hItemWnd = GetDlgItem(hwndDlg, IDC_VARIABLE_NAME);
437         GetWindowRect(hItemWnd, &rect);
438         MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
439 
440         if (hdwp)
441         {
442             hdwp = DeferWindowPos(hdwp,
443                                   hItemWnd,
444                                   NULL,
445                                   0, 0,
446                                   (rect.right - rect.left) + (cx - DlgData->cxOld),
447                                   rect.bottom - rect.top,
448                                   SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
449         }
450 
451         hItemWnd = GetDlgItem(hwndDlg, IDC_VARIABLE_VALUE);
452         GetWindowRect(hItemWnd, &rect);
453         MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
454 
455         if (hdwp)
456         {
457             hdwp = DeferWindowPos(hdwp,
458                                   hItemWnd,
459                                   NULL,
460                                   0, 0,
461                                   (rect.right - rect.left) + (cx - DlgData->cxOld),
462                                   rect.bottom - rect.top,
463                                   SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
464         }
465     }
466     else if (DlgData->dwDlgID == IDD_EDIT_VARIABLE_FANCY)
467     {
468         hdwp = BeginDeferWindowPos(11);
469 
470         /* For the list view control */
471         hItemWnd = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE);
472         GetWindowRect(hItemWnd, &rect);
473         MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
474 
475         if (hdwp)
476         {
477             hdwp = DeferWindowPos(hdwp,
478                                   hItemWnd,
479                                   NULL,
480                                   0, 0,
481                                   (rect.right - rect.left) + (cx - DlgData->cxOld),
482                                   (rect.bottom - rect.top) + (cy - DlgData->cyOld),
483                                   SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
484             ListView_SetColumnWidth(hItemWnd, 0, (rect.right - rect.left) + (cx - DlgData->cxOld));
485         }
486 
487         /* For the buttons */
488         hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_BROWSE_FOLDER);
489         GetWindowRect(hItemWnd, &rect);
490         MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
491 
492         if (hdwp)
493         {
494             hdwp = DeferWindowPos(hdwp,
495                                   hItemWnd,
496                                   NULL,
497                                   rect.left + (cx - DlgData->cxOld),
498                                   rect.top,
499                                   0, 0,
500                                   SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
501         }
502 
503         hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_NEW);
504         GetWindowRect(hItemWnd, &rect);
505         MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
506 
507         if (hdwp)
508         {
509             hdwp = DeferWindowPos(hdwp,
510                                   hItemWnd,
511                                   NULL,
512                                   rect.left + (cx - DlgData->cxOld),
513                                   rect.top,
514                                   0, 0,
515                                   SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
516         }
517 
518         hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_EDIT);
519         GetWindowRect(hItemWnd, &rect);
520         MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
521 
522         if (hdwp)
523         {
524             hdwp = DeferWindowPos(hdwp,
525                                   hItemWnd,
526                                   NULL,
527                                   rect.left + (cx - DlgData->cxOld),
528                                   rect.top,
529                                   0, 0,
530                                   SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
531         }
532 
533         hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_DELETE);
534         GetWindowRect(hItemWnd, &rect);
535         MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
536 
537         if (hdwp)
538         {
539             hdwp = DeferWindowPos(hdwp,
540                                   hItemWnd,
541                                   NULL,
542                                   rect.left + (cx - DlgData->cxOld),
543                                   rect.top,
544                                   0, 0,
545                                   SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
546         }
547 
548         hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_MOVE_UP);
549         GetWindowRect(hItemWnd, &rect);
550         MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
551 
552         if (hdwp)
553         {
554             hdwp = DeferWindowPos(hdwp,
555                                   hItemWnd,
556                                   NULL,
557                                   rect.left + (cx - DlgData->cxOld),
558                                   rect.top,
559                                   0, 0,
560                                   SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
561         }
562 
563         hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_MOVE_DOWN);
564         GetWindowRect(hItemWnd, &rect);
565         MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
566 
567         if (hdwp)
568         {
569             hdwp = DeferWindowPos(hdwp,
570                                   hItemWnd,
571                                   NULL,
572                                   rect.left + (cx - DlgData->cxOld),
573                                   rect.top,
574                                   0, 0,
575                                   SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
576         }
577 
578         hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_EDIT_TEXT);
579         GetWindowRect(hItemWnd, &rect);
580         MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
581 
582         if (hdwp)
583         {
584             hdwp = DeferWindowPos(hdwp,
585                                   hItemWnd,
586                                   NULL,
587                                   rect.left + (cx - DlgData->cxOld),
588                                   rect.top,
589                                   0, 0,
590                                   SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
591         }
592     }
593 
594     hItemWnd = GetDlgItem(hwndDlg, IDOK);
595     GetWindowRect(hItemWnd, &rect);
596     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
597 
598     if (hdwp)
599     {
600         hdwp = DeferWindowPos(hdwp,
601                               hItemWnd,
602                               NULL,
603                               rect.left + (cx - DlgData->cxOld),
604                               rect.top + (cy - DlgData->cyOld),
605                               0, 0,
606                               SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
607     }
608 
609     hItemWnd = GetDlgItem(hwndDlg, IDCANCEL);
610     GetWindowRect(hItemWnd, &rect);
611     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
612 
613     if (hdwp)
614     {
615         hdwp = DeferWindowPos(hdwp,
616                               hItemWnd,
617                               NULL,
618                               rect.left + (cx - DlgData->cxOld),
619                               rect.top + (cy - DlgData->cyOld),
620                               0, 0,
621                               SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
622     }
623 
624     /* For the size grip */
625     hItemWnd = GetDlgItem(hwndDlg, IDC_DIALOG_GRIP);
626     GetWindowRect(hItemWnd, &rect);
627     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
628 
629     if (hdwp)
630     {
631         hdwp = DeferWindowPos(hdwp,
632                               hItemWnd,
633                               NULL,
634                               rect.left + (cx - DlgData->cxOld),
635                               rect.top + (cy - DlgData->cyOld),
636                               0, 0,
637                               SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
638     }
639 
640     if (hdwp)
641     {
642         EndDeferWindowPos(hdwp);
643     }
644 
645     DlgData->cxOld = cx;
646     DlgData->cyOld = cy;
647 }
648 
649 static BOOL
OnBeginLabelEdit(NMLVDISPINFO * pnmv)650 OnBeginLabelEdit(NMLVDISPINFO* pnmv)
651 {
652     HWND hwndEdit;
653 
654     hwndEdit = ListView_GetEditControl(pnmv->hdr.hwndFrom);
655     if (hwndEdit == NULL)
656     {
657         return TRUE;
658     }
659 
660     SendMessage(hwndEdit, EM_SETLIMITTEXT, MAX_PATH - 1, 0);
661 
662     return FALSE;
663 }
664 
665 static BOOL
OnEndLabelEdit(NMLVDISPINFO * pnmv)666 OnEndLabelEdit(NMLVDISPINFO* pnmv)
667 {
668     HWND hwndEdit;
669     TCHAR szOldDir[MAX_PATH];
670     TCHAR szNewDir[MAX_PATH];
671 
672     hwndEdit = ListView_GetEditControl(pnmv->hdr.hwndFrom);
673     if (hwndEdit == NULL)
674     {
675         return TRUE;
676     }
677 
678     /* Leave, if there is no valid listview item */
679     if (pnmv->item.iItem == -1)
680     {
681         return FALSE;
682     }
683 
684     ListView_GetItemText(pnmv->hdr.hwndFrom,
685                          pnmv->item.iItem, 0,
686                          szOldDir,
687                          _countof(szOldDir));
688 
689     SendMessage(hwndEdit, WM_GETTEXT, _countof(szNewDir), (LPARAM)szNewDir);
690 
691     /* If there is nothing in the text box then remove the item */
692     if (_tcslen(szNewDir) == 0)
693     {
694         ListView_DeleteItem(pnmv->hdr.hwndFrom, pnmv->item.iItem);
695         ListView_SetItemState(pnmv->hdr.hwndFrom, pnmv->item.iItem - 1,
696                               LVIS_FOCUSED | LVIS_SELECTED,
697                               LVIS_FOCUSED | LVIS_SELECTED);
698         return FALSE;
699     }
700 
701     /* If nothing has been changed then just bail out */
702     if (_tcscmp(szOldDir, szNewDir) == 0)
703     {
704         return FALSE;
705     }
706 
707     ListView_SetItemText(pnmv->hdr.hwndFrom,
708                          pnmv->item.iItem, 0,
709                          szNewDir);
710 
711     return TRUE;
712 }
713 
714 static BOOL
OnNotifyEditVariableDlg(HWND hwndDlg,PEDIT_DIALOG_DATA DlgData,NMHDR * phdr)715 OnNotifyEditVariableDlg(HWND hwndDlg, PEDIT_DIALOG_DATA DlgData, NMHDR *phdr)
716 {
717     LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
718 
719     switch (phdr->idFrom)
720     {
721         case IDC_LIST_VARIABLE_VALUE:
722             switch (phdr->code)
723             {
724                 case NM_CLICK:
725                 {
726                     /* Detect if an item is selected */
727                     DlgData->bIsItemSelected = (lpnmlv->iItem != -1);
728                     if (lpnmlv->iItem != -1)
729                     {
730                         DlgData->dwSelectedValueIndex = lpnmlv->iItem;
731                     }
732                     break;
733                 }
734 
735                 case NM_DBLCLK:
736                 {
737                     /* Either simulate IDC_BUTTON_NEW or edit an item depending upon the condition */
738                     if (lpnmlv->iItem == -1)
739                     {
740                         SendMessage(GetDlgItem(hwndDlg, IDC_BUTTON_NEW), BM_CLICK, 0, 0);
741                     }
742                     else
743                     {
744                         ListView_EditLabel(GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE), DlgData->dwSelectedValueIndex);
745                     }
746                     break;
747                 }
748 
749                 case LVN_BEGINLABELEDIT:
750                 {
751                     return OnBeginLabelEdit((NMLVDISPINFO*)phdr);
752                 }
753 
754                 case LVN_ENDLABELEDIT:
755                 {
756                     return OnEndLabelEdit((NMLVDISPINFO*)phdr);
757                 }
758             }
759             break;
760     }
761 
762     return FALSE;
763 }
764 
765 static INT_PTR CALLBACK
EditVariableDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)766 EditVariableDlgProc(HWND hwndDlg,
767                     UINT uMsg,
768                     WPARAM wParam,
769                     LPARAM lParam)
770 {
771     PEDIT_DIALOG_DATA DlgData;
772     HWND hwndListView;
773 
774     DlgData = (PEDIT_DIALOG_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
775     hwndListView = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE);
776 
777     switch (uMsg)
778     {
779         case WM_INITDIALOG:
780         {
781             RECT rect;
782 
783             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
784             DlgData = (PEDIT_DIALOG_DATA)lParam;
785 
786             GetClientRect(hwndDlg, &rect);
787             DlgData->cxOld = rect.right - rect.left;
788             DlgData->cyOld = rect.bottom - rect.top;
789 
790             GetWindowRect(hwndDlg, &rect);
791             DlgData->cxMin = rect.right - rect.left;
792             DlgData->cyMin = rect.bottom - rect.top;
793 
794             /* Either get the values from list box or from edit box */
795             if (DlgData->dwDlgID == IDD_EDIT_VARIABLE_FANCY)
796             {
797                 /* Subclass the listview control first */
798                 SetWindowSubclass(hwndListView, ListViewSubclassProc, 1, 0);
799 
800                 if (DlgData->VarData->lpRawValue != NULL)
801                 {
802                     AddValuesToList(hwndDlg, DlgData);
803                 }
804             }
805             else
806             {
807                 if (DlgData->VarData->lpName != NULL)
808                 {
809                     SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_SETTEXT, 0, (LPARAM)DlgData->VarData->lpName);
810                 }
811 
812                 if (DlgData->VarData->lpRawValue != NULL)
813                 {
814                     SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_SETTEXT, 0, (LPARAM)DlgData->VarData->lpRawValue);
815                 }
816             }
817             break;
818         }
819 
820         case WM_SIZE:
821         {
822             OnEnvironmentEditDlgResize(hwndDlg, DlgData, LOWORD(lParam), HIWORD(lParam));
823             SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, 0);
824             return TRUE;
825         }
826 
827         case WM_SIZING:
828         {
829             /* Forbid resizing the dialog smaller than its minimal size */
830             PRECT pRect = (PRECT)lParam;
831 
832             if ((wParam == WMSZ_LEFT) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_BOTTOMLEFT))
833             {
834                 if (pRect->right - pRect->left < DlgData->cxMin)
835                     pRect->left = pRect->right - DlgData->cxMin;
836             }
837             else
838             if ((wParam == WMSZ_RIGHT) || (wParam == WMSZ_TOPRIGHT) || (wParam == WMSZ_BOTTOMRIGHT))
839             {
840                 if (pRect->right - pRect->left < DlgData->cxMin)
841                     pRect->right = pRect->left + DlgData->cxMin;
842             }
843 
844             if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT))
845             {
846                 if (pRect->bottom - pRect->top < DlgData->cyMin)
847                     pRect->top = pRect->bottom - DlgData->cyMin;
848             }
849             else
850             if ((wParam == WMSZ_BOTTOM) || (wParam == WMSZ_BOTTOMLEFT) || (wParam == WMSZ_BOTTOMRIGHT))
851             {
852                 if (pRect->bottom - pRect->top < DlgData->cyMin)
853                     pRect->bottom = pRect->top + DlgData->cyMin;
854             }
855 
856             /* Make sure the normal variable edit dialog doesn't change its height */
857             if (DlgData->dwDlgID == IDD_EDIT_VARIABLE)
858             {
859                 if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT))
860                 {
861                     if (pRect->bottom - pRect->top > DlgData->cyMin)
862                         pRect->top = pRect->bottom - DlgData->cyMin;
863                 }
864                 else
865                 if ((wParam == WMSZ_BOTTOM) || (wParam == WMSZ_BOTTOMLEFT) || (wParam == WMSZ_BOTTOMRIGHT))
866                 {
867                     if (pRect->bottom - pRect->top > DlgData->cyMin)
868                         pRect->bottom = pRect->top + DlgData->cyMin;
869                 }
870             }
871 
872             SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, TRUE);
873             return TRUE;
874         }
875 
876         case WM_NOTIFY:
877         {
878             return OnNotifyEditVariableDlg(hwndDlg, DlgData, (NMHDR*)lParam);
879         }
880 
881         case WM_COMMAND:
882             switch (LOWORD(wParam))
883             {
884                 case IDOK:
885                 {
886                     LPTSTR p;
887                     DWORD dwValueLength;
888 
889                     /* Either set the values to the list box or to the edit box */
890                     if (DlgData->dwDlgID == IDD_EDIT_VARIABLE_FANCY)
891                     {
892                         dwValueLength = GatherDataFromListView(hwndListView, DlgData->VarData);
893                     }
894                     else
895                     {
896                         dwValueLength = GatherDataFromEditBox(hwndDlg, DlgData->VarData);
897                     }
898 
899                     if (dwValueLength == 0)
900                     {
901                         break;
902                     }
903 
904                     if (DlgData->VarData->lpCookedValue != NULL)
905                     {
906                         GlobalFree(DlgData->VarData->lpCookedValue);
907                         DlgData->VarData->lpCookedValue = NULL;
908                     }
909 
910                     p = _tcschr(DlgData->VarData->lpRawValue, _T('%'));
911                     if (p && _tcschr(++p, _T('%')))
912                     {
913                         DlgData->VarData->dwType = REG_EXPAND_SZ;
914 
915                         DlgData->VarData->lpCookedValue = GlobalAlloc(GPTR, 2 * MAX_PATH * sizeof(TCHAR));
916                         if (!DlgData->VarData->lpCookedValue)
917                             return FALSE;
918 
919                         ExpandEnvironmentStrings(DlgData->VarData->lpRawValue,
920                                                  DlgData->VarData->lpCookedValue,
921                                                  2 * MAX_PATH);
922                     }
923                     else
924                     {
925                         DlgData->VarData->dwType = REG_SZ;
926 
927                         DlgData->VarData->lpCookedValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR));
928                         if (!DlgData->VarData->lpCookedValue)
929                             return FALSE;
930 
931                         _tcscpy(DlgData->VarData->lpCookedValue, DlgData->VarData->lpRawValue);
932                     }
933 
934                     EndDialog(hwndDlg, 1);
935                     return TRUE;
936                 }
937 
938                 case IDCANCEL:
939                     EndDialog(hwndDlg, 0);
940                     return TRUE;
941 
942                 case IDC_BUTTON_BROWSE_FILE:
943                 {
944                     BrowseRequiredFile(hwndDlg);
945                     break;
946                 }
947 
948                 case IDC_BUTTON_BROWSE_FOLDER:
949                 {
950                     BrowseRequiredFolder(hwndDlg, DlgData);
951                     break;
952                 }
953 
954                 case IDC_BUTTON_DELETE:
955                 {
956                     DWORD dwLastIndex;
957 
958                     dwLastIndex = ListView_GetItemCount(hwndListView) - 1;
959                     ListView_DeleteItem(hwndListView, DlgData->dwSelectedValueIndex);
960 
961                     if (dwLastIndex == DlgData->dwSelectedValueIndex)
962                     {
963                         DlgData->dwSelectedValueIndex--;
964                     }
965 
966                     ListView_SetItemState(hwndListView, DlgData->dwSelectedValueIndex,
967                                           LVIS_FOCUSED | LVIS_SELECTED,
968                                           LVIS_FOCUSED | LVIS_SELECTED);
969                     break;
970                 }
971 
972                 case IDC_BUTTON_MOVE_UP:
973                 {
974                     MoveListItem(hwndDlg, DlgData, TRUE);
975                     break;
976                 }
977 
978                 case IDC_BUTTON_MOVE_DOWN:
979                 {
980                     MoveListItem(hwndDlg, DlgData, FALSE);
981                     break;
982                 }
983 
984                 case IDC_BUTTON_EDIT_TEXT:
985                 {
986                     if (ResourceMessageBox(hApplet,
987                                            hwndDlg,
988                                            MB_OKCANCEL | MB_ICONWARNING | MB_DEFBUTTON1,
989                                            IDS_ENVIRONMENT_WARNING_TITLE,
990                                            IDS_ENVIRONMENT_WARNING) == IDOK)
991                     {
992                         EndDialog(hwndDlg, -1);
993                     }
994                     break;
995                 }
996 
997                 case IDC_BUTTON_NEW:
998                 {
999                     DlgData->dwSelectedValueIndex = ListView_GetItemCount(hwndListView);
1000                     AddEmptyItem(hwndListView, DlgData->dwSelectedValueIndex);
1001                     ListView_EditLabel(hwndListView, DlgData->dwSelectedValueIndex);
1002                     break;
1003                 }
1004 
1005                 case IDC_BUTTON_EDIT:
1006                 {
1007                     ListView_EditLabel(hwndListView, DlgData->dwSelectedValueIndex);
1008                     break;
1009                 }
1010             }
1011             break;
1012     }
1013 
1014     return FALSE;
1015 }
1016 
1017 
1018 static VOID
GetEnvironmentVariables(HWND hwndListView,HKEY hRootKey,LPTSTR lpSubKeyName)1019 GetEnvironmentVariables(HWND hwndListView,
1020                         HKEY hRootKey,
1021                         LPTSTR lpSubKeyName)
1022 {
1023     HKEY hKey;
1024     DWORD dwValues;
1025     DWORD dwMaxValueNameLength;
1026     DWORD dwMaxValueDataLength;
1027     DWORD i;
1028     LPTSTR lpName;
1029     LPTSTR lpData;
1030     LPTSTR lpExpandData;
1031     DWORD dwNameLength;
1032     DWORD dwDataLength;
1033     DWORD dwType;
1034     PVARIABLE_DATA VarData;
1035 
1036     LV_ITEM lvi;
1037     int iItem;
1038 
1039     if (RegOpenKeyEx(hRootKey,
1040                      lpSubKeyName,
1041                      0,
1042                      KEY_READ,
1043                      &hKey))
1044         return;
1045 
1046     if (RegQueryInfoKey(hKey,
1047                         NULL,
1048                         NULL,
1049                         NULL,
1050                         NULL,
1051                         NULL,
1052                         NULL,
1053                         &dwValues,
1054                         &dwMaxValueNameLength,
1055                         &dwMaxValueDataLength,
1056                         NULL,
1057                         NULL))
1058     {
1059         RegCloseKey(hKey);
1060         return;
1061     }
1062 
1063     lpName = GlobalAlloc(GPTR, (dwMaxValueNameLength + 1) * sizeof(TCHAR));
1064     if (lpName == NULL)
1065     {
1066         RegCloseKey(hKey);
1067         return;
1068     }
1069 
1070     lpData = GlobalAlloc(GPTR, (dwMaxValueDataLength + 1) * sizeof(TCHAR));
1071     if (lpData == NULL)
1072     {
1073         GlobalFree(lpName);
1074         RegCloseKey(hKey);
1075         return;
1076     }
1077 
1078     lpExpandData = GlobalAlloc(GPTR, 2048 * sizeof(TCHAR));
1079     if (lpExpandData == NULL)
1080     {
1081         GlobalFree(lpName);
1082         GlobalFree(lpData);
1083         RegCloseKey(hKey);
1084         return;
1085     }
1086 
1087     for (i = 0; i < dwValues; i++)
1088     {
1089         dwNameLength = dwMaxValueNameLength + 1;
1090         dwDataLength = dwMaxValueDataLength + 1;
1091 
1092         if (RegEnumValue(hKey,
1093                          i,
1094                          lpName,
1095                          &dwNameLength,
1096                          NULL,
1097                          &dwType,
1098                          (LPBYTE)lpData,
1099                          &dwDataLength))
1100         {
1101             GlobalFree(lpExpandData);
1102             GlobalFree(lpName);
1103             GlobalFree(lpData);
1104             RegCloseKey(hKey);
1105             return;
1106         }
1107 
1108         if (dwType != REG_SZ && dwType != REG_EXPAND_SZ)
1109             continue;
1110 
1111         VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA));
1112 
1113         VarData->dwType = dwType;
1114 
1115         VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR));
1116         _tcscpy(VarData->lpName, lpName);
1117 
1118         VarData->lpRawValue = GlobalAlloc(GPTR, (dwDataLength + 1) * sizeof(TCHAR));
1119         _tcscpy(VarData->lpRawValue, lpData);
1120 
1121         ExpandEnvironmentStrings(lpData, lpExpandData, 2048);
1122 
1123         VarData->lpCookedValue = GlobalAlloc(GPTR, (_tcslen(lpExpandData) + 1) * sizeof(TCHAR));
1124         _tcscpy(VarData->lpCookedValue, lpExpandData);
1125 
1126         memset(&lvi, 0x00, sizeof(lvi));
1127         lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
1128         lvi.lParam = (LPARAM)VarData;
1129         lvi.pszText = VarData->lpName;
1130         lvi.state = (i == 0) ? LVIS_SELECTED : 0;
1131         iItem = ListView_InsertItem(hwndListView, &lvi);
1132 
1133         ListView_SetItemText(hwndListView, iItem, 1, VarData->lpCookedValue);
1134     }
1135 
1136     GlobalFree(lpExpandData);
1137     GlobalFree(lpName);
1138     GlobalFree(lpData);
1139     RegCloseKey(hKey);
1140 }
1141 
1142 
1143 static VOID
SetEnvironmentDialogListViewColumns(HWND hwndListView)1144 SetEnvironmentDialogListViewColumns(HWND hwndListView)
1145 {
1146     RECT rect;
1147     LV_COLUMN column;
1148     TCHAR szStr[32];
1149 
1150     GetClientRect(hwndListView, &rect);
1151 
1152     memset(&column, 0x00, sizeof(column));
1153     column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
1154     column.fmt=LVCFMT_LEFT;
1155     column.cx = (INT)((rect.right - rect.left) * 0.32);
1156     column.iSubItem = 0;
1157     LoadString(hApplet, IDS_VARIABLE, szStr, sizeof(szStr) / sizeof(szStr[0]));
1158     column.pszText = szStr;
1159     (void)ListView_InsertColumn(hwndListView, 0, &column);
1160 
1161     column.cx = (INT)((rect.right - rect.left) * 0.63);
1162     column.iSubItem = 1;
1163     LoadString(hApplet, IDS_VALUE, szStr, sizeof(szStr) / sizeof(szStr[0]));
1164     column.pszText = szStr;
1165     (void)ListView_InsertColumn(hwndListView, 1, &column);
1166 }
1167 
1168 
1169 static VOID
OnInitEnvironmentDialog(HWND hwndDlg)1170 OnInitEnvironmentDialog(HWND hwndDlg)
1171 {
1172     HWND hwndListView;
1173 
1174     /* Set user environment variables */
1175     hwndListView = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_LIST);
1176 
1177     (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT);
1178 
1179     SetEnvironmentDialogListViewColumns(hwndListView);
1180 
1181     GetEnvironmentVariables(hwndListView,
1182                             HKEY_CURRENT_USER,
1183                             _T("Environment"));
1184 
1185     (void)ListView_SetColumnWidth(hwndListView, 2, LVSCW_AUTOSIZE_USEHEADER);
1186 
1187     ListView_SetItemState(hwndListView, 0,
1188                           LVIS_FOCUSED | LVIS_SELECTED,
1189                           LVIS_FOCUSED | LVIS_SELECTED);
1190 
1191     (void)ListView_Update(hwndListView,0);
1192 
1193     /* Set system environment variables */
1194     hwndListView = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
1195 
1196     (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT);
1197 
1198     SetEnvironmentDialogListViewColumns(hwndListView);
1199 
1200     GetEnvironmentVariables(hwndListView,
1201                             HKEY_LOCAL_MACHINE,
1202                             _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"));
1203 
1204     (void)ListView_SetColumnWidth(hwndListView, 2, LVSCW_AUTOSIZE_USEHEADER);
1205 
1206     ListView_SetItemState(hwndListView, 0,
1207                           LVIS_FOCUSED | LVIS_SELECTED,
1208                           LVIS_FOCUSED | LVIS_SELECTED);
1209 
1210     (void)ListView_Update(hwndListView, 0);
1211 }
1212 
1213 
1214 static VOID
OnNewVariable(HWND hwndDlg,INT iDlgItem)1215 OnNewVariable(HWND hwndDlg,
1216               INT iDlgItem)
1217 {
1218     HWND hwndListView;
1219     PEDIT_DIALOG_DATA DlgData;
1220     LV_ITEM lvi;
1221     INT iItem;
1222 
1223     DlgData = GlobalAlloc(GPTR, sizeof(EDIT_DIALOG_DATA));
1224     if (!DlgData)
1225         return;
1226 
1227     hwndListView = GetDlgItem(hwndDlg, iDlgItem);
1228     DlgData->dwDlgID = IDD_EDIT_VARIABLE;
1229     DlgData->dwSelectedValueIndex = -1;
1230 
1231     DlgData->VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA));
1232     if (!DlgData->VarData)
1233         return;
1234 
1235     if (DialogBoxParam(hApplet,
1236                        MAKEINTRESOURCE(DlgData->dwDlgID),
1237                        hwndDlg,
1238                        EditVariableDlgProc,
1239                        (LPARAM)DlgData) <= 0)
1240     {
1241         if (DlgData->VarData->lpName != NULL)
1242             GlobalFree(DlgData->VarData->lpName);
1243 
1244         if (DlgData->VarData->lpRawValue != NULL)
1245             GlobalFree(DlgData->VarData->lpRawValue);
1246 
1247         if (DlgData->VarData->lpCookedValue != NULL)
1248             GlobalFree(DlgData->VarData->lpCookedValue);
1249 
1250         GlobalFree(DlgData);
1251     }
1252     else
1253     {
1254         if (DlgData->VarData->lpName != NULL && (DlgData->VarData->lpCookedValue || DlgData->VarData->lpRawValue))
1255         {
1256             ZeroMemory(&lvi, sizeof(lvi));
1257             lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
1258             lvi.lParam = (LPARAM)DlgData->VarData;
1259             lvi.pszText = DlgData->VarData->lpName;
1260             lvi.state = 0;
1261             iItem = ListView_InsertItem(hwndListView, &lvi);
1262 
1263             ListView_SetItemText(hwndListView, iItem, 1, DlgData->VarData->lpCookedValue);
1264         }
1265     }
1266 }
1267 
1268 
1269 static VOID
OnEditVariable(HWND hwndDlg,INT iDlgItem)1270 OnEditVariable(HWND hwndDlg,
1271                INT iDlgItem)
1272 {
1273     HWND hwndListView;
1274     PEDIT_DIALOG_DATA DlgData;
1275     LV_ITEM lvi;
1276     INT iItem;
1277     INT iRet;
1278 
1279     DlgData = GlobalAlloc(GPTR, sizeof(EDIT_DIALOG_DATA));
1280     if (!DlgData)
1281         return;
1282 
1283     DlgData->dwDlgID = IDD_EDIT_VARIABLE;
1284     DlgData->dwSelectedValueIndex = -1;
1285 
1286     hwndListView = GetDlgItem(hwndDlg, iDlgItem);
1287 
1288     iItem = GetSelectedListViewItem(hwndListView);
1289     if (iItem != -1)
1290     {
1291         ZeroMemory(&lvi, sizeof(lvi));
1292         lvi.mask = LVIF_PARAM;
1293         lvi.iItem = iItem;
1294 
1295         if (ListView_GetItem(hwndListView, &lvi))
1296         {
1297             DlgData->VarData = (PVARIABLE_DATA)lvi.lParam;
1298 
1299             /* If the value has multiple values and directories then edit value with fancy dialog box */
1300             if (DetermineDialogBoxType(DlgData->VarData->lpRawValue))
1301                 DlgData->dwDlgID = IDD_EDIT_VARIABLE_FANCY;
1302 
1303             iRet = DialogBoxParam(hApplet,
1304                                   MAKEINTRESOURCE(DlgData->dwDlgID),
1305                                   hwndDlg,
1306                                   EditVariableDlgProc,
1307                                   (LPARAM)DlgData);
1308 
1309             /* If iRet is less than 0 edit the value and name normally */
1310             if (iRet < 0)
1311             {
1312                 DlgData->dwDlgID = IDD_EDIT_VARIABLE;
1313                 iRet = DialogBoxParam(hApplet,
1314                                       MAKEINTRESOURCE(DlgData->dwDlgID),
1315                                       hwndDlg,
1316                                       EditVariableDlgProc,
1317                                       (LPARAM)DlgData);
1318             }
1319 
1320             if (iRet > 0)
1321             {
1322                 ListView_SetItemText(hwndListView, iItem, 0, DlgData->VarData->lpName);
1323                 ListView_SetItemText(hwndListView, iItem, 1, DlgData->VarData->lpCookedValue);
1324             }
1325         }
1326 
1327         GlobalFree(DlgData);
1328     }
1329 }
1330 
1331 
1332 static VOID
OnDeleteVariable(HWND hwndDlg,INT iDlgItem)1333 OnDeleteVariable(HWND hwndDlg,
1334                  INT iDlgItem)
1335 {
1336     HWND hwndListView;
1337     PVARIABLE_DATA VarData;
1338     LV_ITEM lvi;
1339     INT iItem;
1340 
1341     hwndListView = GetDlgItem(hwndDlg, iDlgItem);
1342 
1343     iItem = GetSelectedListViewItem(hwndListView);
1344     if (iItem != -1)
1345     {
1346         memset(&lvi, 0x00, sizeof(lvi));
1347         lvi.mask = LVIF_PARAM;
1348         lvi.iItem = iItem;
1349 
1350         if (ListView_GetItem(hwndListView, &lvi))
1351         {
1352             VarData = (PVARIABLE_DATA)lvi.lParam;
1353             if (VarData != NULL)
1354             {
1355                 if (VarData->lpName != NULL)
1356                     GlobalFree(VarData->lpName);
1357 
1358                 if (VarData->lpRawValue != NULL)
1359                     GlobalFree(VarData->lpRawValue);
1360 
1361                 if (VarData->lpCookedValue != NULL)
1362                     GlobalFree(VarData->lpCookedValue);
1363 
1364                 GlobalFree(VarData);
1365                 lvi.lParam = 0;
1366             }
1367         }
1368 
1369         (void)ListView_DeleteItem(hwndListView, iItem);
1370 
1371         /* Select the previous item */
1372         if (iItem > 0)
1373             iItem--;
1374 
1375         ListView_SetItemState(hwndListView, iItem,
1376                               LVIS_FOCUSED | LVIS_SELECTED,
1377                               LVIS_FOCUSED | LVIS_SELECTED);
1378     }
1379 }
1380 
1381 static VOID
OnEnvironmentDlgResize(HWND hwndDlg,PENVIRONMENT_DIALOG_DATA DlgData,DWORD cx,DWORD cy)1382 OnEnvironmentDlgResize(HWND hwndDlg,
1383                        PENVIRONMENT_DIALOG_DATA DlgData,
1384                        DWORD cx,
1385                        DWORD cy)
1386 {
1387     RECT rect;
1388     INT Colx, y = 0;
1389     HDWP hdwp = NULL;
1390     HWND hItemWnd;
1391 
1392     if ((cx == DlgData->cxOld) && (cy == DlgData->cyOld))
1393         return;
1394 
1395     hdwp = BeginDeferWindowPos(13);
1396 
1397     if (cy >= DlgData->cyOld)
1398         y += (cy - DlgData->cyOld + 1) / 2;
1399     else
1400         y -= (DlgData->cyOld - cy + 1) / 2;
1401 
1402     /* For the group box controls */
1403     hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_GROUP);
1404     GetWindowRect(hItemWnd, &rect);
1405     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1406 
1407     if (hdwp)
1408     {
1409         hdwp = DeferWindowPos(hdwp,
1410                               hItemWnd,
1411                               NULL,
1412                               0, 0,
1413                               (rect.right - rect.left) + (cx - DlgData->cxOld),
1414                               (rect.bottom - rect.top) + y,
1415                               SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
1416     }
1417 
1418     hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_GROUP);
1419     GetWindowRect(hItemWnd, &rect);
1420     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1421 
1422     if (hdwp)
1423     {
1424         hdwp = DeferWindowPos(hdwp,
1425                               hItemWnd,
1426                               NULL,
1427                               rect.left, rect.top + y,
1428                               (rect.right - rect.left) + (cx - DlgData->cxOld),
1429                               (rect.bottom - rect.top) + y,
1430                               SWP_NOZORDER | SWP_NOACTIVATE);
1431     }
1432 
1433     /* For the list view controls */
1434     hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_LIST);
1435     GetWindowRect(hItemWnd, &rect);
1436     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1437 
1438     if (hdwp)
1439     {
1440         hdwp = DeferWindowPos(hdwp,
1441                               hItemWnd,
1442                               NULL,
1443                               0, 0,
1444                               (rect.right - rect.left) + (cx - DlgData->cxOld),
1445                               (rect.bottom - rect.top) + y,
1446                               SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
1447         Colx = ListView_GetColumnWidth(hItemWnd, 1);
1448         ListView_SetColumnWidth(hItemWnd, 1, Colx + (cx - DlgData->cxOld));
1449     }
1450 
1451     hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
1452     GetWindowRect(hItemWnd, &rect);
1453     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1454 
1455     if (hdwp)
1456     {
1457         hdwp = DeferWindowPos(hdwp,
1458                               hItemWnd,
1459                               NULL,
1460                               rect.left, rect.top + y,
1461                               (rect.right - rect.left) + (cx - DlgData->cxOld),
1462                               (rect.bottom - rect.top) + y,
1463                               SWP_NOZORDER | SWP_NOACTIVATE);
1464         Colx = ListView_GetColumnWidth(hItemWnd, 1);
1465         ListView_SetColumnWidth(hItemWnd, 1, Colx + (cx - DlgData->cxOld));
1466     }
1467 
1468     /* For the buttons */
1469     hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_NEW);
1470     GetWindowRect(hItemWnd, &rect);
1471     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1472 
1473     if (hdwp)
1474     {
1475         hdwp = DeferWindowPos(hdwp,
1476                               hItemWnd,
1477                               NULL,
1478                               rect.left + (cx - DlgData->cxOld),
1479                               rect.top + y,
1480                               0, 0,
1481                               SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
1482     }
1483 
1484     hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_EDIT);
1485     GetWindowRect(hItemWnd, &rect);
1486     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1487 
1488     if (hdwp)
1489     {
1490         hdwp = DeferWindowPos(hdwp,
1491                               hItemWnd,
1492                               NULL,
1493                               rect.left + (cx - DlgData->cxOld),
1494                               rect.top + y,
1495                               0, 0,
1496                               SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
1497     }
1498 
1499     hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_DELETE);
1500     GetWindowRect(hItemWnd, &rect);
1501     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1502 
1503     if (hdwp)
1504     {
1505         hdwp = DeferWindowPos(hdwp,
1506                               hItemWnd,
1507                               NULL,
1508                               rect.left + (cx - DlgData->cxOld),
1509                               rect.top + y,
1510                               0, 0,
1511                               SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
1512     }
1513 
1514     hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_NEW);
1515     GetWindowRect(hItemWnd, &rect);
1516     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1517 
1518     if (hdwp)
1519     {
1520         hdwp = DeferWindowPos(hdwp,
1521                               hItemWnd,
1522                               NULL,
1523                               rect.left + (cx - DlgData->cxOld),
1524                               rect.top + y * 2,
1525                               0, 0,
1526                               SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
1527     }
1528 
1529     hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_EDIT);
1530     GetWindowRect(hItemWnd, &rect);
1531     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1532 
1533     if (hdwp)
1534     {
1535         hdwp = DeferWindowPos(hdwp,
1536                               hItemWnd,
1537                               NULL,
1538                               rect.left + (cx - DlgData->cxOld),
1539                               rect.top + y * 2,
1540                               0, 0,
1541                               SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
1542     }
1543 
1544     hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_DELETE);
1545     GetWindowRect(hItemWnd, &rect);
1546     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1547 
1548     if (hdwp)
1549     {
1550         hdwp = DeferWindowPos(hdwp,
1551                               hItemWnd,
1552                               NULL,
1553                               rect.left + (cx - DlgData->cxOld),
1554                               rect.top + y * 2,
1555                               0, 0,
1556                               SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
1557     }
1558 
1559     hItemWnd = GetDlgItem(hwndDlg, IDOK);
1560     GetWindowRect(hItemWnd, &rect);
1561     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1562 
1563     if (hdwp)
1564     {
1565         hdwp = DeferWindowPos(hdwp,
1566                               hItemWnd,
1567                               NULL,
1568                               rect.left + (cx - DlgData->cxOld),
1569                               rect.top + (cy - DlgData->cyOld),
1570                               0, 0,
1571                               SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
1572     }
1573 
1574     hItemWnd = GetDlgItem(hwndDlg, IDCANCEL);
1575     GetWindowRect(hItemWnd, &rect);
1576     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1577 
1578     if (hdwp)
1579     {
1580         hdwp = DeferWindowPos(hdwp,
1581                               hItemWnd,
1582                               NULL,
1583                               rect.left + (cx - DlgData->cxOld),
1584                               rect.top + (cy - DlgData->cyOld),
1585                               0, 0,
1586                               SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
1587     }
1588 
1589     /* For the size grip */
1590     hItemWnd = GetDlgItem(hwndDlg, IDC_DIALOG_GRIP);
1591     GetWindowRect(hItemWnd, &rect);
1592     MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT));
1593 
1594     if (hdwp)
1595     {
1596         hdwp = DeferWindowPos(hdwp,
1597                               hItemWnd,
1598                               NULL,
1599                               rect.left + (cx - DlgData->cxOld),
1600                               rect.top + (cy - DlgData->cyOld),
1601                               0, 0,
1602                               SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
1603     }
1604 
1605     if (hdwp)
1606     {
1607         EndDeferWindowPos(hdwp);
1608     }
1609 
1610     DlgData->cxOld = cx;
1611     DlgData->cyOld = cy;
1612 }
1613 
1614 static VOID
ReleaseListViewItems(HWND hwndDlg,INT iDlgItem)1615 ReleaseListViewItems(HWND hwndDlg,
1616                      INT iDlgItem)
1617 {
1618     HWND hwndListView;
1619     PVARIABLE_DATA VarData;
1620     LV_ITEM lvi;
1621     INT nItemCount;
1622     INT i;
1623 
1624     hwndListView = GetDlgItem(hwndDlg, iDlgItem);
1625 
1626     memset(&lvi, 0x00, sizeof(lvi));
1627 
1628     nItemCount = ListView_GetItemCount(hwndListView);
1629     for (i = 0; i < nItemCount; i++)
1630     {
1631         lvi.mask = LVIF_PARAM;
1632         lvi.iItem = i;
1633 
1634         if (ListView_GetItem(hwndListView, &lvi))
1635         {
1636             VarData = (PVARIABLE_DATA)lvi.lParam;
1637             if (VarData != NULL)
1638             {
1639                 if (VarData->lpName != NULL)
1640                     GlobalFree(VarData->lpName);
1641 
1642                 if (VarData->lpRawValue != NULL)
1643                     GlobalFree(VarData->lpRawValue);
1644 
1645                 if (VarData->lpCookedValue != NULL)
1646                     GlobalFree(VarData->lpCookedValue);
1647 
1648                 GlobalFree(VarData);
1649                 lvi.lParam = 0;
1650             }
1651         }
1652     }
1653 }
1654 
1655 
1656 static VOID
SetAllVars(HWND hwndDlg,INT iDlgItem)1657 SetAllVars(HWND hwndDlg,
1658            INT iDlgItem)
1659 {
1660     HWND hwndListView;
1661     PVARIABLE_DATA VarData;
1662     LV_ITEM lvi;
1663     INT iItem;
1664     HKEY hKey;
1665     DWORD dwValueCount;
1666     DWORD dwMaxValueNameLength;
1667     LPTSTR *aValueArray;
1668     DWORD dwNameLength;
1669     DWORD i;
1670     TCHAR szBuffer[256];
1671     LPTSTR lpBuffer;
1672 
1673     memset(&lvi, 0x00, sizeof(lvi));
1674 
1675     /* Get the handle to the list box with all system vars in it */
1676     hwndListView = GetDlgItem(hwndDlg, iDlgItem);
1677     /* First item is 0 */
1678     iItem = 0;
1679     /* Set up struct to retrieve item */
1680     lvi.mask = LVIF_PARAM;
1681     lvi.iItem = iItem;
1682 
1683     /* Open or create the key */
1684     if (RegCreateKeyEx((iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER),
1685                        (iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment") : _T("Environment")),
1686                        0,
1687                        NULL,
1688                        REG_OPTION_NON_VOLATILE,
1689                        KEY_WRITE | KEY_READ,
1690                        NULL,
1691                        &hKey,
1692                        NULL))
1693     {
1694         return;
1695     }
1696 
1697     /* Get the number of values and the maximum value name length */
1698     if (RegQueryInfoKey(hKey,
1699                         NULL,
1700                         NULL,
1701                         NULL,
1702                         NULL,
1703                         NULL,
1704                         NULL,
1705                         &dwValueCount,
1706                         &dwMaxValueNameLength,
1707                         NULL,
1708                         NULL,
1709                         NULL))
1710     {
1711         RegCloseKey(hKey);
1712         return;
1713     }
1714 
1715     if (dwValueCount > 0)
1716     {
1717         /* Allocate the value array */
1718         aValueArray = GlobalAlloc(GPTR, dwValueCount * sizeof(LPTSTR));
1719         if (aValueArray != NULL)
1720         {
1721             /* Get all value names */
1722             for (i = 0; i < dwValueCount; i++)
1723             {
1724                 dwNameLength = 256;
1725                 if (!RegEnumValue(hKey,
1726                                   i,
1727                                   szBuffer,
1728                                   &dwNameLength,
1729                                   NULL,
1730                                   NULL,
1731                                   NULL,
1732                                   NULL))
1733                 {
1734                     /* Allocate a value name buffer, fill it and attach it to the array */
1735                     lpBuffer = (LPTSTR)GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR));
1736                     if (lpBuffer != NULL)
1737                     {
1738                         _tcscpy(lpBuffer, szBuffer);
1739                         aValueArray[i] = lpBuffer;
1740                     }
1741                 }
1742             }
1743 
1744             /* Delete all values */
1745             for (i = 0; i < dwValueCount; i++)
1746             {
1747                 if (aValueArray[i] != NULL)
1748                 {
1749                     /* Delete the value */
1750                     RegDeleteValue(hKey,
1751                                    aValueArray[i]);
1752 
1753                     /* Free the value name */
1754                     GlobalFree(aValueArray[i]);
1755                 }
1756             }
1757 
1758             /* Free the value array */
1759             GlobalFree(aValueArray);
1760         }
1761     }
1762 
1763     /* Loop through all variables */
1764     while (ListView_GetItem(hwndListView, &lvi))
1765     {
1766         /* Get the data in each item */
1767         VarData = (PVARIABLE_DATA)lvi.lParam;
1768         if (VarData != NULL)
1769         {
1770             /* Set the new value */
1771             if (RegSetValueEx(hKey,
1772                               VarData->lpName,
1773                               0,
1774                               VarData->dwType,
1775                               (LPBYTE)VarData->lpRawValue,
1776                               (DWORD)(_tcslen(VarData->lpRawValue) + 1) * sizeof(TCHAR)))
1777             {
1778                 RegCloseKey(hKey);
1779                 return;
1780             }
1781         }
1782 
1783         /* Fill struct for next item */
1784         lvi.mask = LVIF_PARAM;
1785         lvi.iItem = ++iItem;
1786     }
1787 
1788     RegCloseKey(hKey);
1789 }
1790 
1791 
1792 static BOOL
OnNotify(HWND hwndDlg,NMHDR * phdr)1793 OnNotify(HWND hwndDlg, NMHDR *phdr)
1794 {
1795     switch (phdr->code)
1796     {
1797         case NM_DBLCLK:
1798             if (phdr->idFrom == IDC_USER_VARIABLE_LIST ||
1799                 phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST)
1800             {
1801                 OnEditVariable(hwndDlg, (INT)phdr->idFrom);
1802                 return TRUE;
1803             }
1804             break;
1805 
1806         case LVN_KEYDOWN:
1807             if (((LPNMLVKEYDOWN)phdr)->wVKey == VK_DELETE &&
1808                 (phdr->idFrom == IDC_USER_VARIABLE_LIST ||
1809                  phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST))
1810             {
1811                 OnDeleteVariable(hwndDlg, (INT)phdr->idFrom);
1812                 return TRUE;
1813             }
1814             break;
1815     }
1816 
1817     return FALSE;
1818 }
1819 
1820 
1821 /* Environment dialog procedure */
1822 INT_PTR CALLBACK
EnvironmentDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)1823 EnvironmentDlgProc(HWND hwndDlg,
1824                    UINT uMsg,
1825                    WPARAM wParam,
1826                    LPARAM lParam)
1827 {
1828     PENVIRONMENT_DIALOG_DATA DlgData;
1829     DlgData = (PENVIRONMENT_DIALOG_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
1830 
1831     switch (uMsg)
1832     {
1833         case WM_INITDIALOG:
1834         {
1835             RECT rect;
1836 
1837             DlgData = GlobalAlloc(GPTR, sizeof(ENVIRONMENT_DIALOG_DATA));
1838             if (!DlgData)
1839             {
1840                 EndDialog(hwndDlg, 0);
1841                 return (INT_PTR)TRUE;
1842             }
1843             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)DlgData);
1844 
1845             GetClientRect(hwndDlg, &rect);
1846             DlgData->cxOld = rect.right - rect.left;
1847             DlgData->cyOld = rect.bottom - rect.top;
1848 
1849             GetWindowRect(hwndDlg, &rect);
1850             DlgData->cxMin = rect.right - rect.left;
1851             DlgData->cyMin = rect.bottom - rect.top;
1852 
1853             OnInitEnvironmentDialog(hwndDlg);
1854             break;
1855         }
1856 
1857         case WM_SIZE:
1858         {
1859             OnEnvironmentDlgResize(hwndDlg, DlgData, LOWORD(lParam), HIWORD(lParam));
1860             SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, 0);
1861             return TRUE;
1862         }
1863 
1864         case WM_SIZING:
1865         {
1866             /* Forbid resizing the dialog smaller than its minimal size */
1867             PRECT pRect = (PRECT)lParam;
1868 
1869             if ((wParam == WMSZ_LEFT) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_BOTTOMLEFT))
1870             {
1871                 if (pRect->right - pRect->left < DlgData->cxMin)
1872                     pRect->left = pRect->right - DlgData->cxMin;
1873             }
1874             else
1875             if ((wParam == WMSZ_RIGHT) || (wParam == WMSZ_TOPRIGHT) || (wParam == WMSZ_BOTTOMRIGHT))
1876             {
1877                 if (pRect->right - pRect->left < DlgData->cxMin)
1878                     pRect->right = pRect->left + DlgData->cxMin;
1879             }
1880 
1881             if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT))
1882             {
1883                 if (pRect->bottom - pRect->top < DlgData->cyMin)
1884                     pRect->top = pRect->bottom - DlgData->cyMin;
1885             }
1886             else
1887             if ((wParam == WMSZ_BOTTOM) || (wParam == WMSZ_BOTTOMLEFT) || (wParam == WMSZ_BOTTOMRIGHT))
1888             {
1889                 if (pRect->bottom - pRect->top < DlgData->cyMin)
1890                     pRect->bottom = pRect->top + DlgData->cyMin;
1891             }
1892 
1893             SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, TRUE);
1894             return TRUE;
1895         }
1896 
1897         case WM_COMMAND:
1898             switch (LOWORD(wParam))
1899             {
1900                 case IDC_USER_VARIABLE_NEW:
1901                     OnNewVariable(hwndDlg, IDC_USER_VARIABLE_LIST);
1902                     return TRUE;
1903 
1904                 case IDC_USER_VARIABLE_EDIT:
1905                     OnEditVariable(hwndDlg, IDC_USER_VARIABLE_LIST);
1906                     return TRUE;
1907 
1908                 case IDC_USER_VARIABLE_DELETE:
1909                     OnDeleteVariable(hwndDlg, IDC_USER_VARIABLE_LIST);
1910                     return TRUE;
1911 
1912                 case IDC_SYSTEM_VARIABLE_NEW:
1913                     OnNewVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
1914                     return TRUE;
1915 
1916                 case IDC_SYSTEM_VARIABLE_EDIT:
1917                     OnEditVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
1918                     return TRUE;
1919 
1920                 case IDC_SYSTEM_VARIABLE_DELETE:
1921                     OnDeleteVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
1922                     return TRUE;
1923 
1924                 case IDOK:
1925                     SetAllVars(hwndDlg, IDC_USER_VARIABLE_LIST);
1926                     SetAllVars(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
1927                     SendMessage(HWND_BROADCAST, WM_WININICHANGE,
1928                                 0, (LPARAM)_T("Environment"));
1929                     EndDialog(hwndDlg, 0);
1930                     return TRUE;
1931 
1932                 case IDCANCEL:
1933                     EndDialog(hwndDlg, 0);
1934                     return TRUE;
1935             }
1936             break;
1937 
1938         case WM_DESTROY:
1939             ReleaseListViewItems(hwndDlg, IDC_USER_VARIABLE_LIST);
1940             ReleaseListViewItems(hwndDlg, IDC_SYSTEM_VARIABLE_LIST);
1941             GlobalFree(DlgData);
1942             break;
1943 
1944         case WM_NOTIFY:
1945             return OnNotify(hwndDlg, (NMHDR*)lParam);
1946     }
1947 
1948     return FALSE;
1949 }
1950 
1951 /* EOF */
1952