/* * PROJECT: ReactOS System Control Panel Applet * LICENSE: GPL - See COPYING in the top level directory * FILE: dll/cpl/sysdm/environment.c * PURPOSE: Environment variable settings * COPYRIGHT: Copyright Eric Kohl * Copyright 2021 Arnav Bhatt */ #include "precomp.h" #include #include #include typedef struct _VARIABLE_DATA { DWORD dwType; LPTSTR lpName; LPTSTR lpRawValue; LPTSTR lpCookedValue; } VARIABLE_DATA, *PVARIABLE_DATA; typedef struct _ENVIRONMENT_DIALOG_DATA { DWORD cxMin; DWORD cyMin; DWORD cxOld; DWORD cyOld; } ENVIRONMENT_DIALOG_DATA, *PENVIRONMENT_DIALOG_DATA; typedef struct _ENVIRONMENT_EDIT_DIALOG_DATA { BOOL bIsItemSelected; DWORD dwSelectedValueIndex; DWORD cxMin; DWORD cyMin; DWORD cxOld; DWORD cyOld; DWORD dwDlgID; HWND hEditBox; PVARIABLE_DATA VarData; } EDIT_DIALOG_DATA, *PEDIT_DIALOG_DATA; static BOOL DetermineDialogBoxType(LPTSTR lpRawValue) { DWORD dwValueLength; LPTSTR lpTemp; LPTSTR lpToken; dwValueLength = _tcslen(lpRawValue) + 1; lpTemp = GlobalAlloc(GPTR, dwValueLength * sizeof(TCHAR)); if (!lpTemp) return FALSE; StringCchCopy(lpTemp, dwValueLength, lpRawValue); for (lpToken = _tcstok(lpTemp, _T(";")); lpToken != NULL; lpToken = _tcstok(NULL, _T(";"))) { /* If the string has environment variable then expand it */ ExpandEnvironmentStrings(lpToken, lpToken, dwValueLength); if (!PathIsDirectoryW(lpToken)) return FALSE; } GlobalFree(lpTemp); return TRUE; } static DWORD GatherDataFromEditBox(HWND hwndDlg, PVARIABLE_DATA VarData) { DWORD dwNameLength; DWORD dwValueLength; dwNameLength = SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_GETTEXTLENGTH, 0, 0); dwValueLength = SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_GETTEXTLENGTH, 0, 0); if (dwNameLength == 0 || dwValueLength == 0) { return 0; } /* Reallocate the name buffer, regrowing it if necessary */ if (!VarData->lpName || (_tcslen(VarData->lpName) < dwNameLength)) { if (VarData->lpName) GlobalFree(VarData->lpName); VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR)); if (!VarData->lpName) return 0; } SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_GETTEXT, dwNameLength + 1, (LPARAM)VarData->lpName); /* Reallocate the value buffer, regrowing it if necessary */ if (!VarData->lpRawValue || (_tcslen(VarData->lpRawValue) < dwValueLength)) { if (VarData->lpRawValue) GlobalFree(VarData->lpRawValue); VarData->lpRawValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR)); if (!VarData->lpRawValue) return 0; } SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_GETTEXT, dwValueLength + 1, (LPARAM)VarData->lpRawValue); return dwValueLength; } static DWORD GatherDataFromListView(HWND hwndListView, PVARIABLE_DATA VarData) { DWORD dwValueLength; DWORD NumberOfItems; DWORD i; TCHAR szData[MAX_PATH]; /* Gather the number of items for the semi-colon */ NumberOfItems = ListView_GetItemCount(hwndListView); if (NumberOfItems == 0) { return 0; } /* Since the last item doesn't need the semi-colon subtract 1 */ dwValueLength = NumberOfItems - 1; for (i = 0; i < NumberOfItems; i++) { ListView_GetItemText(hwndListView, i, 0, szData, _countof(szData)); dwValueLength += _tcslen(szData); } /* Reallocate the value buffer, regrowing it if necessary */ if (!VarData->lpRawValue || (_tcslen(VarData->lpRawValue) < dwValueLength)) { if (VarData->lpRawValue) GlobalFree(VarData->lpRawValue); VarData->lpRawValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR)); if (!VarData->lpRawValue) return 0; } /* First reinitialize the value buffer, then copy the variable values while * separating them with a semi-colon, except for the last value. */ VarData->lpRawValue[0] = _T('\0'); for (i = 0; i < NumberOfItems; i++) { if (i > 0) { StringCchCat(VarData->lpRawValue, dwValueLength + 1, _T(";")); } ListView_GetItemText(hwndListView, i, 0, szData, _countof(szData)); StringCchCat(VarData->lpRawValue, dwValueLength + 1, szData); } return dwValueLength; } static INT GetSelectedListViewItem(HWND hwndListView) { INT iCount; INT iItem; iCount = SendMessage(hwndListView, LVM_GETITEMCOUNT, 0, 0); if (iCount != LB_ERR) { for (iItem = 0; iItem < iCount; iItem++) { if (SendMessage(hwndListView, LVM_GETITEMSTATE, iItem, (LPARAM) LVIS_SELECTED) == LVIS_SELECTED) { return iItem; } } } return -1; } static LRESULT CALLBACK ListViewSubclassProc(HWND hListBox, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { switch (uMsg) { case WM_DESTROY: { RemoveWindowSubclass(hListBox, ListViewSubclassProc, uIdSubclass); break; } /* Whenever the control is resized make sure it doesn't spawn the horizontal scrollbar */ case WM_SIZE: { ShowScrollBar(hListBox, SB_HORZ, FALSE); break; } } return DefSubclassProc(hListBox, uMsg, wParam, lParam); } static VOID AddEmptyItem(HWND hwndListView, DWORD dwSelectedValueIndex) { LV_ITEM lvi; ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_TEXT | LVIF_STATE; lvi.cchTextMax = MAX_PATH; lvi.pszText = _T(""); lvi.iItem = dwSelectedValueIndex; lvi.iSubItem = 0; ListView_InsertItem(hwndListView, &lvi); } static VOID AddValuesToList(HWND hwndDlg, PEDIT_DIALOG_DATA DlgData) { LV_COLUMN column; LV_ITEM lvi; RECT rItem; DWORD dwValueLength; DWORD i; HWND hwndListView; LPTSTR lpTemp; LPTSTR lpToken; ZeroMemory(&column, sizeof(column)); ZeroMemory(&lvi, sizeof(lvi)); hwndListView = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE); GetClientRect(hwndListView, &rItem); column.mask = LVCF_WIDTH; column.cx = rItem.right; ListView_InsertColumn(hwndListView, 0, &column); ShowScrollBar(hwndListView, SB_HORZ, FALSE); lvi.mask = LVIF_TEXT | LVIF_STATE; lvi.cchTextMax = MAX_PATH; lvi.iSubItem = 0; dwValueLength = _tcslen(DlgData->VarData->lpRawValue) + 1; lpTemp = GlobalAlloc(GPTR, dwValueLength * sizeof(TCHAR)); if (!lpTemp) return; StringCchCopy(lpTemp, dwValueLength, DlgData->VarData->lpRawValue); for (lpToken = _tcstok(lpTemp, _T(";")), i = 0; lpToken != NULL; lpToken = _tcstok(NULL, _T(";")), i++) { lvi.iItem = i; lvi.pszText = lpToken; lvi.state = (i == 0) ? LVIS_SELECTED : 0; ListView_InsertItem(hwndListView, &lvi); } DlgData->dwSelectedValueIndex = 0; ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT); ListView_SetItemState(hwndListView, DlgData->dwSelectedValueIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); ListView_Update(hwndListView, DlgData->dwSelectedValueIndex); GlobalFree(lpTemp); } static VOID BrowseRequiredFile(HWND hwndDlg) { OPENFILENAME ofn; TCHAR szFilter[MAX_STR_LENGTH] = _T(""); TCHAR szFile[MAX_PATH] = _T(""); LoadString(hApplet, IDS_FILE_BROWSE_FILTER, szFilter, _countof(szFilter)); ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwndDlg; ofn.lpstrFilter = szFilter; ofn.lpstrFile = szFile; ofn.nMaxFile = _countof(szFile); ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; if (GetOpenFileName(&ofn)) { SetDlgItemText(hwndDlg, IDC_VARIABLE_VALUE, szFile); } } static VOID BrowseRequiredFolder(HWND hwndDlg, PEDIT_DIALOG_DATA DlgData) { HWND hwndListView; TCHAR szDir[MAX_PATH]; BROWSEINFO bi; LPITEMIDLIST pidllist; ZeroMemory(&bi, sizeof(bi)); bi.hwndOwner = hwndDlg; bi.ulFlags = BIF_NEWDIALOGSTYLE; hwndListView = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE); pidllist = SHBrowseForFolder(&bi); if (!pidllist) { return; } if (SHGetPathFromIDList(pidllist, szDir)) { if (DlgData->dwDlgID == IDD_EDIT_VARIABLE_FANCY) { /* If no item is selected then create a new empty item and add the required location to it */ if (!DlgData->bIsItemSelected) { DlgData->dwSelectedValueIndex = ListView_GetItemCount(hwndListView); AddEmptyItem(hwndListView, DlgData->dwSelectedValueIndex); } ListView_SetItemText(hwndListView, DlgData->dwSelectedValueIndex, 0, szDir); ListView_SetItemState(hwndListView, DlgData->dwSelectedValueIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); } else { SetDlgItemText(hwndDlg, IDC_VARIABLE_VALUE, szDir); } } CoTaskMemFree(pidllist); } static VOID MoveListItem(HWND hwndDlg, PEDIT_DIALOG_DATA DlgData, BOOL bMoveUp) { TCHAR szDest[MAX_PATH]; TCHAR szSource[MAX_PATH]; HWND hwndListView; DWORD dwSrcIndex, dwDestIndex, dwLastIndex; hwndListView = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE); dwLastIndex = ListView_GetItemCount(hwndListView) - 1; dwSrcIndex = DlgData->dwSelectedValueIndex; dwDestIndex = bMoveUp ? (dwSrcIndex - 1) : (dwSrcIndex + 1); if ((bMoveUp && dwSrcIndex > 0) || (!bMoveUp && dwSrcIndex < dwLastIndex)) { ListView_GetItemText(hwndListView, dwSrcIndex, 0, szDest, _countof(szDest)); ListView_GetItemText(hwndListView, dwDestIndex, 0, szSource, _countof(szSource)); ListView_SetItemText(hwndListView, dwDestIndex, 0, szDest); ListView_SetItemText(hwndListView, dwSrcIndex, 0, szSource); DlgData->dwSelectedValueIndex = dwDestIndex; ListView_SetItemState(hwndListView, DlgData->dwSelectedValueIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); } } static VOID OnEnvironmentEditDlgResize(HWND hwndDlg, PEDIT_DIALOG_DATA DlgData, DWORD cx, DWORD cy) { RECT rect; HDWP hdwp = NULL; HWND hItemWnd; if ((cx == DlgData->cxOld) && (cy == DlgData->cyOld)) return; if (DlgData->dwDlgID == IDD_EDIT_VARIABLE) { hdwp = BeginDeferWindowPos(5); /* For the edit control */ hItemWnd = GetDlgItem(hwndDlg, IDC_VARIABLE_NAME); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, 0, 0, (rect.right - rect.left) + (cx - DlgData->cxOld), rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_VARIABLE_VALUE); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, 0, 0, (rect.right - rect.left) + (cx - DlgData->cxOld), rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); } } else if (DlgData->dwDlgID == IDD_EDIT_VARIABLE_FANCY) { hdwp = BeginDeferWindowPos(11); /* For the list view control */ hItemWnd = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, 0, 0, (rect.right - rect.left) + (cx - DlgData->cxOld), (rect.bottom - rect.top) + (cy - DlgData->cyOld), SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); ListView_SetColumnWidth(hItemWnd, 0, (rect.right - rect.left) + (cx - DlgData->cxOld)); } /* For the buttons */ hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_BROWSE_FOLDER); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_NEW); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_EDIT); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_DELETE); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_MOVE_UP); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_MOVE_DOWN); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_BUTTON_EDIT_TEXT); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } } hItemWnd = GetDlgItem(hwndDlg, IDOK); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top + (cy - DlgData->cyOld), 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDCANCEL); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top + (cy - DlgData->cyOld), 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } /* For the size grip */ hItemWnd = GetDlgItem(hwndDlg, IDC_DIALOG_GRIP); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top + (cy - DlgData->cyOld), 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } if (hdwp) { EndDeferWindowPos(hdwp); } DlgData->cxOld = cx; DlgData->cyOld = cy; } static BOOL OnBeginLabelEdit(NMLVDISPINFO* pnmv) { HWND hwndEdit; hwndEdit = ListView_GetEditControl(pnmv->hdr.hwndFrom); if (hwndEdit == NULL) { return TRUE; } SendMessage(hwndEdit, EM_SETLIMITTEXT, MAX_PATH - 1, 0); return FALSE; } static BOOL OnEndLabelEdit(NMLVDISPINFO* pnmv) { HWND hwndEdit; TCHAR szOldDir[MAX_PATH]; TCHAR szNewDir[MAX_PATH]; hwndEdit = ListView_GetEditControl(pnmv->hdr.hwndFrom); if (hwndEdit == NULL) { return TRUE; } /* Leave, if there is no valid listview item */ if (pnmv->item.iItem == -1) { return FALSE; } ListView_GetItemText(pnmv->hdr.hwndFrom, pnmv->item.iItem, 0, szOldDir, _countof(szOldDir)); SendMessage(hwndEdit, WM_GETTEXT, _countof(szNewDir), (LPARAM)szNewDir); /* If there is nothing in the text box then remove the item */ if (_tcslen(szNewDir) == 0) { ListView_DeleteItem(pnmv->hdr.hwndFrom, pnmv->item.iItem); ListView_SetItemState(pnmv->hdr.hwndFrom, pnmv->item.iItem - 1, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); return FALSE; } /* If nothing has been changed then just bail out */ if (_tcscmp(szOldDir, szNewDir) == 0) { return FALSE; } ListView_SetItemText(pnmv->hdr.hwndFrom, pnmv->item.iItem, 0, szNewDir); return TRUE; } static BOOL OnNotifyEditVariableDlg(HWND hwndDlg, PEDIT_DIALOG_DATA DlgData, NMHDR *phdr) { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr; switch (phdr->idFrom) { case IDC_LIST_VARIABLE_VALUE: switch (phdr->code) { case NM_CLICK: { /* Detect if an item is selected */ DlgData->bIsItemSelected = (lpnmlv->iItem != -1); if (lpnmlv->iItem != -1) { DlgData->dwSelectedValueIndex = lpnmlv->iItem; } break; } case NM_DBLCLK: { /* Either simulate IDC_BUTTON_NEW or edit an item depending upon the condition */ if (lpnmlv->iItem == -1) { SendMessage(GetDlgItem(hwndDlg, IDC_BUTTON_NEW), BM_CLICK, 0, 0); } else { ListView_EditLabel(GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE), DlgData->dwSelectedValueIndex); } break; } case LVN_BEGINLABELEDIT: { return OnBeginLabelEdit((NMLVDISPINFO*)phdr); } case LVN_ENDLABELEDIT: { return OnEndLabelEdit((NMLVDISPINFO*)phdr); } } break; } return FALSE; } static INT_PTR CALLBACK EditVariableDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { PEDIT_DIALOG_DATA DlgData; HWND hwndListView; DlgData = (PEDIT_DIALOG_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); hwndListView = GetDlgItem(hwndDlg, IDC_LIST_VARIABLE_VALUE); switch (uMsg) { case WM_INITDIALOG: { RECT rect; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam); DlgData = (PEDIT_DIALOG_DATA)lParam; GetClientRect(hwndDlg, &rect); DlgData->cxOld = rect.right - rect.left; DlgData->cyOld = rect.bottom - rect.top; GetWindowRect(hwndDlg, &rect); DlgData->cxMin = rect.right - rect.left; DlgData->cyMin = rect.bottom - rect.top; /* Either get the values from list box or from edit box */ if (DlgData->dwDlgID == IDD_EDIT_VARIABLE_FANCY) { /* Subclass the listview control first */ SetWindowSubclass(hwndListView, ListViewSubclassProc, 1, 0); if (DlgData->VarData->lpRawValue != NULL) { AddValuesToList(hwndDlg, DlgData); } } else { if (DlgData->VarData->lpName != NULL) { SendDlgItemMessage(hwndDlg, IDC_VARIABLE_NAME, WM_SETTEXT, 0, (LPARAM)DlgData->VarData->lpName); } if (DlgData->VarData->lpRawValue != NULL) { SendDlgItemMessage(hwndDlg, IDC_VARIABLE_VALUE, WM_SETTEXT, 0, (LPARAM)DlgData->VarData->lpRawValue); } } break; } case WM_SIZE: { OnEnvironmentEditDlgResize(hwndDlg, DlgData, LOWORD(lParam), HIWORD(lParam)); SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, 0); return TRUE; } case WM_SIZING: { /* Forbid resizing the dialog smaller than its minimal size */ PRECT pRect = (PRECT)lParam; if ((wParam == WMSZ_LEFT) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_BOTTOMLEFT)) { if (pRect->right - pRect->left < DlgData->cxMin) pRect->left = pRect->right - DlgData->cxMin; } else if ((wParam == WMSZ_RIGHT) || (wParam == WMSZ_TOPRIGHT) || (wParam == WMSZ_BOTTOMRIGHT)) { if (pRect->right - pRect->left < DlgData->cxMin) pRect->right = pRect->left + DlgData->cxMin; } if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT)) { if (pRect->bottom - pRect->top < DlgData->cyMin) pRect->top = pRect->bottom - DlgData->cyMin; } else if ((wParam == WMSZ_BOTTOM) || (wParam == WMSZ_BOTTOMLEFT) || (wParam == WMSZ_BOTTOMRIGHT)) { if (pRect->bottom - pRect->top < DlgData->cyMin) pRect->bottom = pRect->top + DlgData->cyMin; } /* Make sure the normal variable edit dialog doesn't change its height */ if (DlgData->dwDlgID == IDD_EDIT_VARIABLE) { if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT)) { if (pRect->bottom - pRect->top > DlgData->cyMin) pRect->top = pRect->bottom - DlgData->cyMin; } else if ((wParam == WMSZ_BOTTOM) || (wParam == WMSZ_BOTTOMLEFT) || (wParam == WMSZ_BOTTOMRIGHT)) { if (pRect->bottom - pRect->top > DlgData->cyMin) pRect->bottom = pRect->top + DlgData->cyMin; } } SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, TRUE); return TRUE; } case WM_NOTIFY: { return OnNotifyEditVariableDlg(hwndDlg, DlgData, (NMHDR*)lParam); } case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: { LPTSTR p; DWORD dwValueLength; /* Either set the values to the list box or to the edit box */ if (DlgData->dwDlgID == IDD_EDIT_VARIABLE_FANCY) { dwValueLength = GatherDataFromListView(hwndListView, DlgData->VarData); } else { dwValueLength = GatherDataFromEditBox(hwndDlg, DlgData->VarData); } if (dwValueLength == 0) { break; } if (DlgData->VarData->lpCookedValue != NULL) { GlobalFree(DlgData->VarData->lpCookedValue); DlgData->VarData->lpCookedValue = NULL; } p = _tcschr(DlgData->VarData->lpRawValue, _T('%')); if (p && _tcschr(++p, _T('%'))) { DlgData->VarData->dwType = REG_EXPAND_SZ; DlgData->VarData->lpCookedValue = GlobalAlloc(GPTR, 2 * MAX_PATH * sizeof(TCHAR)); if (!DlgData->VarData->lpCookedValue) return FALSE; ExpandEnvironmentStrings(DlgData->VarData->lpRawValue, DlgData->VarData->lpCookedValue, 2 * MAX_PATH); } else { DlgData->VarData->dwType = REG_SZ; DlgData->VarData->lpCookedValue = GlobalAlloc(GPTR, (dwValueLength + 1) * sizeof(TCHAR)); if (!DlgData->VarData->lpCookedValue) return FALSE; _tcscpy(DlgData->VarData->lpCookedValue, DlgData->VarData->lpRawValue); } EndDialog(hwndDlg, 1); return TRUE; } case IDCANCEL: EndDialog(hwndDlg, 0); return TRUE; case IDC_BUTTON_BROWSE_FILE: { BrowseRequiredFile(hwndDlg); break; } case IDC_BUTTON_BROWSE_FOLDER: { BrowseRequiredFolder(hwndDlg, DlgData); break; } case IDC_BUTTON_DELETE: { DWORD dwLastIndex; dwLastIndex = ListView_GetItemCount(hwndListView) - 1; ListView_DeleteItem(hwndListView, DlgData->dwSelectedValueIndex); if (dwLastIndex == DlgData->dwSelectedValueIndex) { DlgData->dwSelectedValueIndex--; } ListView_SetItemState(hwndListView, DlgData->dwSelectedValueIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); break; } case IDC_BUTTON_MOVE_UP: { MoveListItem(hwndDlg, DlgData, TRUE); break; } case IDC_BUTTON_MOVE_DOWN: { MoveListItem(hwndDlg, DlgData, FALSE); break; } case IDC_BUTTON_EDIT_TEXT: { if (ResourceMessageBox(hApplet, hwndDlg, MB_OKCANCEL | MB_ICONWARNING | MB_DEFBUTTON1, IDS_ENVIRONMENT_WARNING_TITLE, IDS_ENVIRONMENT_WARNING) == IDOK) { EndDialog(hwndDlg, -1); } break; } case IDC_BUTTON_NEW: { DlgData->dwSelectedValueIndex = ListView_GetItemCount(hwndListView); AddEmptyItem(hwndListView, DlgData->dwSelectedValueIndex); ListView_EditLabel(hwndListView, DlgData->dwSelectedValueIndex); break; } case IDC_BUTTON_EDIT: { ListView_EditLabel(hwndListView, DlgData->dwSelectedValueIndex); break; } } break; } return FALSE; } static VOID GetEnvironmentVariables(HWND hwndListView, HKEY hRootKey, LPTSTR lpSubKeyName) { HKEY hKey; DWORD dwValues; DWORD dwMaxValueNameLength; DWORD dwMaxValueDataLength; DWORD i; LPTSTR lpName; LPTSTR lpData; LPTSTR lpExpandData; DWORD dwNameLength; DWORD dwDataLength; DWORD dwType; PVARIABLE_DATA VarData; LV_ITEM lvi; int iItem; if (RegOpenKeyEx(hRootKey, lpSubKeyName, 0, KEY_READ, &hKey)) return; if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValues, &dwMaxValueNameLength, &dwMaxValueDataLength, NULL, NULL)) { RegCloseKey(hKey); return; } lpName = GlobalAlloc(GPTR, (dwMaxValueNameLength + 1) * sizeof(TCHAR)); if (lpName == NULL) { RegCloseKey(hKey); return; } lpData = GlobalAlloc(GPTR, (dwMaxValueDataLength + 1) * sizeof(TCHAR)); if (lpData == NULL) { GlobalFree(lpName); RegCloseKey(hKey); return; } lpExpandData = GlobalAlloc(GPTR, 2048 * sizeof(TCHAR)); if (lpExpandData == NULL) { GlobalFree(lpName); GlobalFree(lpData); RegCloseKey(hKey); return; } for (i = 0; i < dwValues; i++) { dwNameLength = dwMaxValueNameLength + 1; dwDataLength = dwMaxValueDataLength + 1; if (RegEnumValue(hKey, i, lpName, &dwNameLength, NULL, &dwType, (LPBYTE)lpData, &dwDataLength)) { GlobalFree(lpExpandData); GlobalFree(lpName); GlobalFree(lpData); RegCloseKey(hKey); return; } if (dwType != REG_SZ && dwType != REG_EXPAND_SZ) continue; VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA)); VarData->dwType = dwType; VarData->lpName = GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR)); _tcscpy(VarData->lpName, lpName); VarData->lpRawValue = GlobalAlloc(GPTR, (dwDataLength + 1) * sizeof(TCHAR)); _tcscpy(VarData->lpRawValue, lpData); ExpandEnvironmentStrings(lpData, lpExpandData, 2048); VarData->lpCookedValue = GlobalAlloc(GPTR, (_tcslen(lpExpandData) + 1) * sizeof(TCHAR)); _tcscpy(VarData->lpCookedValue, lpExpandData); memset(&lvi, 0x00, sizeof(lvi)); lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM; lvi.lParam = (LPARAM)VarData; lvi.pszText = VarData->lpName; lvi.state = (i == 0) ? LVIS_SELECTED : 0; iItem = ListView_InsertItem(hwndListView, &lvi); ListView_SetItemText(hwndListView, iItem, 1, VarData->lpCookedValue); } GlobalFree(lpExpandData); GlobalFree(lpName); GlobalFree(lpData); RegCloseKey(hKey); } static VOID SetEnvironmentDialogListViewColumns(HWND hwndListView) { RECT rect; LV_COLUMN column; TCHAR szStr[32]; GetClientRect(hwndListView, &rect); memset(&column, 0x00, sizeof(column)); column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT; column.fmt=LVCFMT_LEFT; column.cx = (INT)((rect.right - rect.left) * 0.32); column.iSubItem = 0; LoadString(hApplet, IDS_VARIABLE, szStr, sizeof(szStr) / sizeof(szStr[0])); column.pszText = szStr; (void)ListView_InsertColumn(hwndListView, 0, &column); column.cx = (INT)((rect.right - rect.left) * 0.63); column.iSubItem = 1; LoadString(hApplet, IDS_VALUE, szStr, sizeof(szStr) / sizeof(szStr[0])); column.pszText = szStr; (void)ListView_InsertColumn(hwndListView, 1, &column); } static VOID OnInitEnvironmentDialog(HWND hwndDlg) { HWND hwndListView; /* Set user environment variables */ hwndListView = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_LIST); (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT); SetEnvironmentDialogListViewColumns(hwndListView); GetEnvironmentVariables(hwndListView, HKEY_CURRENT_USER, _T("Environment")); (void)ListView_SetColumnWidth(hwndListView, 2, LVSCW_AUTOSIZE_USEHEADER); ListView_SetItemState(hwndListView, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); (void)ListView_Update(hwndListView,0); /* Set system environment variables */ hwndListView = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT); SetEnvironmentDialogListViewColumns(hwndListView); GetEnvironmentVariables(hwndListView, HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment")); (void)ListView_SetColumnWidth(hwndListView, 2, LVSCW_AUTOSIZE_USEHEADER); ListView_SetItemState(hwndListView, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); (void)ListView_Update(hwndListView, 0); } static VOID OnNewVariable(HWND hwndDlg, INT iDlgItem) { HWND hwndListView; PEDIT_DIALOG_DATA DlgData; LV_ITEM lvi; INT iItem; DlgData = GlobalAlloc(GPTR, sizeof(EDIT_DIALOG_DATA)); if (!DlgData) return; hwndListView = GetDlgItem(hwndDlg, iDlgItem); DlgData->dwDlgID = IDD_EDIT_VARIABLE; DlgData->dwSelectedValueIndex = -1; DlgData->VarData = GlobalAlloc(GPTR, sizeof(VARIABLE_DATA)); if (!DlgData->VarData) return; if (DialogBoxParam(hApplet, MAKEINTRESOURCE(DlgData->dwDlgID), hwndDlg, EditVariableDlgProc, (LPARAM)DlgData) <= 0) { if (DlgData->VarData->lpName != NULL) GlobalFree(DlgData->VarData->lpName); if (DlgData->VarData->lpRawValue != NULL) GlobalFree(DlgData->VarData->lpRawValue); if (DlgData->VarData->lpCookedValue != NULL) GlobalFree(DlgData->VarData->lpCookedValue); GlobalFree(DlgData); } else { if (DlgData->VarData->lpName != NULL && (DlgData->VarData->lpCookedValue || DlgData->VarData->lpRawValue)) { ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM; lvi.lParam = (LPARAM)DlgData->VarData; lvi.pszText = DlgData->VarData->lpName; lvi.state = 0; iItem = ListView_InsertItem(hwndListView, &lvi); ListView_SetItemText(hwndListView, iItem, 1, DlgData->VarData->lpCookedValue); } } } static VOID OnEditVariable(HWND hwndDlg, INT iDlgItem) { HWND hwndListView; PEDIT_DIALOG_DATA DlgData; LV_ITEM lvi; INT iItem; INT iRet; DlgData = GlobalAlloc(GPTR, sizeof(EDIT_DIALOG_DATA)); if (!DlgData) return; DlgData->dwDlgID = IDD_EDIT_VARIABLE; DlgData->dwSelectedValueIndex = -1; hwndListView = GetDlgItem(hwndDlg, iDlgItem); iItem = GetSelectedListViewItem(hwndListView); if (iItem != -1) { ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM; lvi.iItem = iItem; if (ListView_GetItem(hwndListView, &lvi)) { DlgData->VarData = (PVARIABLE_DATA)lvi.lParam; /* If the value has multiple values and directories then edit value with fancy dialog box */ if (DetermineDialogBoxType(DlgData->VarData->lpRawValue)) DlgData->dwDlgID = IDD_EDIT_VARIABLE_FANCY; iRet = DialogBoxParam(hApplet, MAKEINTRESOURCE(DlgData->dwDlgID), hwndDlg, EditVariableDlgProc, (LPARAM)DlgData); /* If iRet is less than 0 edit the value and name normally */ if (iRet < 0) { DlgData->dwDlgID = IDD_EDIT_VARIABLE; iRet = DialogBoxParam(hApplet, MAKEINTRESOURCE(DlgData->dwDlgID), hwndDlg, EditVariableDlgProc, (LPARAM)DlgData); } if (iRet > 0) { ListView_SetItemText(hwndListView, iItem, 0, DlgData->VarData->lpName); ListView_SetItemText(hwndListView, iItem, 1, DlgData->VarData->lpCookedValue); } } GlobalFree(DlgData); } } static VOID OnDeleteVariable(HWND hwndDlg, INT iDlgItem) { HWND hwndListView; PVARIABLE_DATA VarData; LV_ITEM lvi; INT iItem; hwndListView = GetDlgItem(hwndDlg, iDlgItem); iItem = GetSelectedListViewItem(hwndListView); if (iItem != -1) { memset(&lvi, 0x00, sizeof(lvi)); lvi.mask = LVIF_PARAM; lvi.iItem = iItem; if (ListView_GetItem(hwndListView, &lvi)) { VarData = (PVARIABLE_DATA)lvi.lParam; if (VarData != NULL) { if (VarData->lpName != NULL) GlobalFree(VarData->lpName); if (VarData->lpRawValue != NULL) GlobalFree(VarData->lpRawValue); if (VarData->lpCookedValue != NULL) GlobalFree(VarData->lpCookedValue); GlobalFree(VarData); lvi.lParam = 0; } } (void)ListView_DeleteItem(hwndListView, iItem); /* Select the previous item */ if (iItem > 0) iItem--; ListView_SetItemState(hwndListView, iItem, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); } } static VOID OnEnvironmentDlgResize(HWND hwndDlg, PENVIRONMENT_DIALOG_DATA DlgData, DWORD cx, DWORD cy) { RECT rect; INT Colx, y = 0; HDWP hdwp = NULL; HWND hItemWnd; if ((cx == DlgData->cxOld) && (cy == DlgData->cyOld)) return; hdwp = BeginDeferWindowPos(13); if (cy >= DlgData->cyOld) y += (cy - DlgData->cyOld + 1) / 2; else y -= (DlgData->cyOld - cy + 1) / 2; /* For the group box controls */ hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_GROUP); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, 0, 0, (rect.right - rect.left) + (cx - DlgData->cxOld), (rect.bottom - rect.top) + y, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_GROUP); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left, rect.top + y, (rect.right - rect.left) + (cx - DlgData->cxOld), (rect.bottom - rect.top) + y, SWP_NOZORDER | SWP_NOACTIVATE); } /* For the list view controls */ hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_LIST); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, 0, 0, (rect.right - rect.left) + (cx - DlgData->cxOld), (rect.bottom - rect.top) + y, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); Colx = ListView_GetColumnWidth(hItemWnd, 1); ListView_SetColumnWidth(hItemWnd, 1, Colx + (cx - DlgData->cxOld)); } hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left, rect.top + y, (rect.right - rect.left) + (cx - DlgData->cxOld), (rect.bottom - rect.top) + y, SWP_NOZORDER | SWP_NOACTIVATE); Colx = ListView_GetColumnWidth(hItemWnd, 1); ListView_SetColumnWidth(hItemWnd, 1, Colx + (cx - DlgData->cxOld)); } /* For the buttons */ hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_NEW); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top + y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_EDIT); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top + y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_USER_VARIABLE_DELETE); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top + y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_NEW); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top + y * 2, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_EDIT); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top + y * 2, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDC_SYSTEM_VARIABLE_DELETE); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top + y * 2, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDOK); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top + (cy - DlgData->cyOld), 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } hItemWnd = GetDlgItem(hwndDlg, IDCANCEL); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top + (cy - DlgData->cyOld), 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } /* For the size grip */ hItemWnd = GetDlgItem(hwndDlg, IDC_DIALOG_GRIP); GetWindowRect(hItemWnd, &rect); MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rect, sizeof(RECT)/sizeof(POINT)); if (hdwp) { hdwp = DeferWindowPos(hdwp, hItemWnd, NULL, rect.left + (cx - DlgData->cxOld), rect.top + (cy - DlgData->cyOld), 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } if (hdwp) { EndDeferWindowPos(hdwp); } DlgData->cxOld = cx; DlgData->cyOld = cy; } static VOID ReleaseListViewItems(HWND hwndDlg, INT iDlgItem) { HWND hwndListView; PVARIABLE_DATA VarData; LV_ITEM lvi; INT nItemCount; INT i; hwndListView = GetDlgItem(hwndDlg, iDlgItem); memset(&lvi, 0x00, sizeof(lvi)); nItemCount = ListView_GetItemCount(hwndListView); for (i = 0; i < nItemCount; i++) { lvi.mask = LVIF_PARAM; lvi.iItem = i; if (ListView_GetItem(hwndListView, &lvi)) { VarData = (PVARIABLE_DATA)lvi.lParam; if (VarData != NULL) { if (VarData->lpName != NULL) GlobalFree(VarData->lpName); if (VarData->lpRawValue != NULL) GlobalFree(VarData->lpRawValue); if (VarData->lpCookedValue != NULL) GlobalFree(VarData->lpCookedValue); GlobalFree(VarData); lvi.lParam = 0; } } } } static VOID SetAllVars(HWND hwndDlg, INT iDlgItem) { HWND hwndListView; PVARIABLE_DATA VarData; LV_ITEM lvi; INT iItem; HKEY hKey; DWORD dwValueCount; DWORD dwMaxValueNameLength; LPTSTR *aValueArray; DWORD dwNameLength; DWORD i; TCHAR szBuffer[256]; LPTSTR lpBuffer; memset(&lvi, 0x00, sizeof(lvi)); /* Get the handle to the list box with all system vars in it */ hwndListView = GetDlgItem(hwndDlg, iDlgItem); /* First item is 0 */ iItem = 0; /* Set up struct to retrieve item */ lvi.mask = LVIF_PARAM; lvi.iItem = iItem; /* Open or create the key */ if (RegCreateKeyEx((iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER), (iDlgItem == IDC_SYSTEM_VARIABLE_LIST ? _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment") : _T("Environment")), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, NULL, &hKey, NULL)) { return; } /* Get the number of values and the maximum value name length */ if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValueCount, &dwMaxValueNameLength, NULL, NULL, NULL)) { RegCloseKey(hKey); return; } if (dwValueCount > 0) { /* Allocate the value array */ aValueArray = GlobalAlloc(GPTR, dwValueCount * sizeof(LPTSTR)); if (aValueArray != NULL) { /* Get all value names */ for (i = 0; i < dwValueCount; i++) { dwNameLength = 256; if (!RegEnumValue(hKey, i, szBuffer, &dwNameLength, NULL, NULL, NULL, NULL)) { /* Allocate a value name buffer, fill it and attach it to the array */ lpBuffer = (LPTSTR)GlobalAlloc(GPTR, (dwNameLength + 1) * sizeof(TCHAR)); if (lpBuffer != NULL) { _tcscpy(lpBuffer, szBuffer); aValueArray[i] = lpBuffer; } } } /* Delete all values */ for (i = 0; i < dwValueCount; i++) { if (aValueArray[i] != NULL) { /* Delete the value */ RegDeleteValue(hKey, aValueArray[i]); /* Free the value name */ GlobalFree(aValueArray[i]); } } /* Free the value array */ GlobalFree(aValueArray); } } /* Loop through all variables */ while (ListView_GetItem(hwndListView, &lvi)) { /* Get the data in each item */ VarData = (PVARIABLE_DATA)lvi.lParam; if (VarData != NULL) { /* Set the new value */ if (RegSetValueEx(hKey, VarData->lpName, 0, VarData->dwType, (LPBYTE)VarData->lpRawValue, (DWORD)(_tcslen(VarData->lpRawValue) + 1) * sizeof(TCHAR))) { RegCloseKey(hKey); return; } } /* Fill struct for next item */ lvi.mask = LVIF_PARAM; lvi.iItem = ++iItem; } RegCloseKey(hKey); } static BOOL OnNotify(HWND hwndDlg, NMHDR *phdr) { switch (phdr->code) { case NM_DBLCLK: if (phdr->idFrom == IDC_USER_VARIABLE_LIST || phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST) { OnEditVariable(hwndDlg, (INT)phdr->idFrom); return TRUE; } break; case LVN_KEYDOWN: if (((LPNMLVKEYDOWN)phdr)->wVKey == VK_DELETE && (phdr->idFrom == IDC_USER_VARIABLE_LIST || phdr->idFrom == IDC_SYSTEM_VARIABLE_LIST)) { OnDeleteVariable(hwndDlg, (INT)phdr->idFrom); return TRUE; } break; } return FALSE; } /* Environment dialog procedure */ INT_PTR CALLBACK EnvironmentDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { PENVIRONMENT_DIALOG_DATA DlgData; DlgData = (PENVIRONMENT_DIALOG_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); switch (uMsg) { case WM_INITDIALOG: { RECT rect; DlgData = GlobalAlloc(GPTR, sizeof(ENVIRONMENT_DIALOG_DATA)); if (!DlgData) { EndDialog(hwndDlg, 0); return (INT_PTR)TRUE; } SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)DlgData); GetClientRect(hwndDlg, &rect); DlgData->cxOld = rect.right - rect.left; DlgData->cyOld = rect.bottom - rect.top; GetWindowRect(hwndDlg, &rect); DlgData->cxMin = rect.right - rect.left; DlgData->cyMin = rect.bottom - rect.top; OnInitEnvironmentDialog(hwndDlg); break; } case WM_SIZE: { OnEnvironmentDlgResize(hwndDlg, DlgData, LOWORD(lParam), HIWORD(lParam)); SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, 0); return TRUE; } case WM_SIZING: { /* Forbid resizing the dialog smaller than its minimal size */ PRECT pRect = (PRECT)lParam; if ((wParam == WMSZ_LEFT) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_BOTTOMLEFT)) { if (pRect->right - pRect->left < DlgData->cxMin) pRect->left = pRect->right - DlgData->cxMin; } else if ((wParam == WMSZ_RIGHT) || (wParam == WMSZ_TOPRIGHT) || (wParam == WMSZ_BOTTOMRIGHT)) { if (pRect->right - pRect->left < DlgData->cxMin) pRect->right = pRect->left + DlgData->cxMin; } if ((wParam == WMSZ_TOP) || (wParam == WMSZ_TOPLEFT) || (wParam == WMSZ_TOPRIGHT)) { if (pRect->bottom - pRect->top < DlgData->cyMin) pRect->top = pRect->bottom - DlgData->cyMin; } else if ((wParam == WMSZ_BOTTOM) || (wParam == WMSZ_BOTTOMLEFT) || (wParam == WMSZ_BOTTOMRIGHT)) { if (pRect->bottom - pRect->top < DlgData->cyMin) pRect->bottom = pRect->top + DlgData->cyMin; } SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, TRUE); return TRUE; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_USER_VARIABLE_NEW: OnNewVariable(hwndDlg, IDC_USER_VARIABLE_LIST); return TRUE; case IDC_USER_VARIABLE_EDIT: OnEditVariable(hwndDlg, IDC_USER_VARIABLE_LIST); return TRUE; case IDC_USER_VARIABLE_DELETE: OnDeleteVariable(hwndDlg, IDC_USER_VARIABLE_LIST); return TRUE; case IDC_SYSTEM_VARIABLE_NEW: OnNewVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); return TRUE; case IDC_SYSTEM_VARIABLE_EDIT: OnEditVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); return TRUE; case IDC_SYSTEM_VARIABLE_DELETE: OnDeleteVariable(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); return TRUE; case IDOK: SetAllVars(hwndDlg, IDC_USER_VARIABLE_LIST); SetAllVars(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM)_T("Environment")); EndDialog(hwndDlg, 0); return TRUE; case IDCANCEL: EndDialog(hwndDlg, 0); return TRUE; } break; case WM_DESTROY: ReleaseListViewItems(hwndDlg, IDC_USER_VARIABLE_LIST); ReleaseListViewItems(hwndDlg, IDC_SYSTEM_VARIABLE_LIST); GlobalFree(DlgData); break; case WM_NOTIFY: return OnNotify(hwndDlg, (NMHDR*)lParam); } return FALSE; } /* EOF */