Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1377 lines
40 KiB

//*************************************************************
//
// Envvar.c - Environment Variables property sheet page
//
// Microsoft Confidential
// Copyright (c) Microsoft Corporation 1996
// All rights reserved
//
//*************************************************************
#include <sysdm.h>
// C Runtime
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
//==========================================================================
// Local Definitions
//==========================================================================
#define LB_SYSVAR 1
#define LB_USERVAR 2
#define BUFZ 4096
#define MAX_VALUE_LEN 1024
//==========================================================================
// Typedefs and Structs
//==========================================================================
// Environment variables structure
typedef struct
{
// DWORD dwLocation;
DWORD dwType;
LPTSTR szValueName;
LPTSTR szValue;
LPTSTR szExpValue;
} ENVARS;
// Registry valuename linked-list structure
typedef struct _regval
{
struct _regval *prvNext;
LPTSTR szValueName;
} REGVAL;
//==========================================================================
// Local Functions
//==========================================================================
void EVDoCommand(HWND hDlg, HWND hwndCtl, int idCtl, int iNotify );
void EVDoItemChanged(HWND hDlg, int idCtl );
void EVSave(HWND hDlg);
void EVCleanUp (HWND hDlg);
int FindVar (HWND hwndLB, LPTSTR szVar);
void ClearAllSelections (HWND hCtrl);
//==========================================================================
// "Global" Variables for this page
//==========================================================================
BOOL bEditSystemVars = FALSE;
DWORD cxLBSysVars = 0;
BOOL bUserVars = TRUE;
//
// Help ID's
//
DWORD aEnvVarsHelpIds[] = {
IDC_ENVVAR_SYS_LB_SYSVARS, (IDH_ENV + 0),
IDC_ENVVAR_SYS_USERENV, (IDH_ENV + 1),
IDC_ENVVAR_SYS_LB_USERVARS, (IDH_ENV + 2),
IDC_ENVVAR_SYS_VAR, (IDH_ENV + 3),
IDC_ENVVAR_SYS_VALUE, (IDH_ENV + 4),
IDC_ENVVAR_SYS_SETUV, (IDH_ENV + 5),
IDC_ENVVAR_SYS_DELUV, (IDH_ENV + 6),
0, 0
};
TCHAR szUserEnv[] = TEXT( "Environment" );
TCHAR szSysEnv[] = TEXT( "System\\CurrentControlSet\\Control\\Session Manager\\Environment" );
//*************************************************************
//
// CreateEnvVarsPage()
//
// Purpose: Creates the Environment Variables page
//
// Parameters: hInst - hInstance
//
//
// Return: hPage if successful
// NULL if an error occurs
//
// Comments:
//
// History: Date Author Comment
// 11/21/95 ericflo Created
//
//*************************************************************
HPROPSHEETPAGE CreateEnvVarsPage (HINSTANCE hInst)
{
PROPSHEETPAGE psp;
psp.dwSize = SIZEOF(PROPSHEETPAGE);
psp.dwFlags = 0;
psp.hInstance = hInst;
psp.pszTemplate = MAKEINTRESOURCE(IDD_ENVVARS);
psp.pfnDlgProc = EnvVarsDlgProc;
psp.pszTitle = NULL;
psp.lParam = 0;
return CreatePropertySheetPage(&psp);
}
//*************************************************************
//
// InitEnvVarsDlg()
//
// Purpose: Initializes the environment variables page
//
// Parameters: hDlg - dialog box handle
//
// Return: (BOOL) TRUE if successful
// FALSE if an error occurs
//
// Comments:
//
// History: Date Author Comment
// 11/25/95 ericflo Created
//
//*************************************************************
BOOL InitEnvVarsDlg (HWND hDlg)
{
TCHAR szBuffer1[200];
TCHAR szBuffer2[300];
TCHAR szUserName[MAX_USER_NAME];
DWORD dwSize = MAX_USER_NAME;
HWND hwndTemp;
HKEY hkeyEnv;
TCHAR *pszValue;
HANDLE hKey;
DWORD dwBufz, dwValz, dwIndex, dwType;
LONG Error;
TCHAR szTemp[MAX_PATH];
LPTSTR pszString;
ENVARS *penvar;
int n;
LV_COLUMN col;
LV_ITEM item;
RECT rect;
int cxFirstCol;
HourGlass (TRUE);
//
// Create the first column
//
LoadString (hInstance, SYSTEM + 50, szBuffer1, 200);
if (!GetClientRect (GetDlgItem(hDlg, IDC_ENVVAR_SYS_LB_SYSVARS), &rect)) {
rect.right = 300;
}
cxFirstCol = (int)(rect.right * .3);
col.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
col.fmt = LVCFMT_LEFT;
col.cx = cxFirstCol;
col.pszText = szBuffer1;
col.iSubItem = 0;
SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_SYSVARS, LVM_INSERTCOLUMN,
0, (LPARAM) &col);
SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_USERVARS, LVM_INSERTCOLUMN,
0, (LPARAM) &col);
//
// Create the second column
//
LoadString (hInstance, SYSTEM + 51, szBuffer1, 200);
col.cx = rect.right - cxFirstCol - GetSystemMetrics(SM_CYHSCROLL);
col.iSubItem = 1;
SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_SYSVARS, LVM_INSERTCOLUMN,
1, (LPARAM) &col);
SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_USERVARS, LVM_INSERTCOLUMN,
1, (LPARAM) &col);
////////////////////////////////////////////////////////////////////
// Display System Variables from registry in listbox
////////////////////////////////////////////////////////////////////
hwndTemp = GetDlgItem (hDlg, IDC_ENVVAR_SYS_LB_SYSVARS);
hKey = MemAlloc (LPTR, BUFZ*SIZEOF(TCHAR));
pszString = (LPTSTR) MemAlloc (LPTR, BUFZ*sizeof(TCHAR));
bEditSystemVars = FALSE;
cxLBSysVars = 0;
hkeyEnv = NULL;
// Try to open the System Environment variables area with
// Read AND Write permission. If successful, then we allow
// the User to edit them the same as their own variables
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, szSysEnv, 0, KEY_READ | KEY_WRITE, &hkeyEnv) != ERROR_SUCCESS) {
// On failure, just try to open it for reading
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, szSysEnv, 0, KEY_READ, &hkeyEnv) != ERROR_SUCCESS) {
hkeyEnv = NULL;
}
} else {
bEditSystemVars = TRUE;
}
if (hkeyEnv)
{
pszValue = (TCHAR *) hKey;
dwBufz = ARRAYSIZE(szTemp);
dwValz = BUFZ * SIZEOF(TCHAR);
dwIndex = 0;
// Read all values until an error is encountered
while (!RegEnumValue(hkeyEnv,
dwIndex++, // Index'th value name/data
szTemp, // Ptr to ValueName buffer
&dwBufz, // Size of ValueName buffer
NULL, // Title index return
&dwType, // Type code of entry
(LPBYTE) pszValue, // Ptr to ValueData buffer
&dwValz)) // Size of ValueData buffer
{
if ((dwType != REG_SZ) && (dwType != REG_EXPAND_SZ))
goto SysLoop;
//
// Clip length of returned Environment variable string
// to MAX_VALUE_LEN-1, as necessary.
//
pszValue[MAX_VALUE_LEN-1] = TEXT('\0');
ExpandEnvironmentStrings (pszValue, pszString, BUFZ);
penvar = (ENVARS *) MemAlloc (LPTR, SIZEOF(ENVARS));
penvar->dwType = dwType;
penvar->szValueName = CloneString( szTemp );
penvar->szValue = CloneString( pszValue );
penvar->szExpValue = CloneString( pszString );
item.mask = LVIF_TEXT | LVIF_PARAM;
item.iItem = (dwIndex - 1);
item.iSubItem = 0;
item.pszText = penvar->szValueName;
item.lParam = (LPARAM) penvar;
n = SendMessage (hwndTemp, LVM_INSERTITEM, 0, (LPARAM) &item);
if (n != -1) {
item.mask = LVIF_TEXT;
item.iItem = n;
item.iSubItem = 1;
item.pszText = penvar->szExpValue;
SendMessage (hwndTemp, LVM_SETITEMTEXT, n, (LPARAM) &item);
}
SysLoop:
// Reset vars for next iteration
dwBufz = ARRAYSIZE(szTemp);
dwValz = BUFZ * SIZEOF(TCHAR);
}
RegCloseKey (hkeyEnv);
}
////////////////////////////////////////////////////////////////////
// Display USER variables from registry in listbox
////////////////////////////////////////////////////////////////////
//
// Set the "User Environments for <username>" string
//
if (GetUserName(szUserName, &dwSize) &&
LoadString (hInstance, IDS_USERENVVARS, szBuffer1, 200)) {
wsprintf (szBuffer2, szBuffer1, szUserName);
SetDlgItemText (hDlg, IDC_ENVVAR_SYS_USERENV, szBuffer2);
}
Error = RegCreateKey (HKEY_CURRENT_USER, szUserEnv, &hkeyEnv);
if (Error == ERROR_SUCCESS)
{
hwndTemp = GetDlgItem (hDlg, IDC_ENVVAR_SYS_LB_USERVARS);
pszValue = (TCHAR *) hKey;
dwBufz = ARRAYSIZE(szTemp);
dwValz = BUFZ * SIZEOF(TCHAR);
dwIndex = 0;
// Read all values until an error is encountered
while (!RegEnumValue(hkeyEnv,
dwIndex++, // Index'th value name/data
szTemp, // Ptr to ValueName buffer
&dwBufz, // Size of ValueName buffer
NULL, // Title index return
&dwType, // Type code of entry
(LPBYTE) pszValue, // Ptr to ValueData buffer
&dwValz)) // Size of ValueData buffer
{
if ((dwType != REG_SZ) && (dwType != REG_EXPAND_SZ))
goto UserLoop;
//
// Clip length of returned Environment variable string
// to MAX_VALUE_LEN-1, as necessary.
//
pszValue[MAX_VALUE_LEN-1] = TEXT('\0');
ExpandEnvironmentStrings (pszValue, pszString, BUFZ);
penvar = (ENVARS *) MemAlloc (LPTR, sizeof(ENVARS));
penvar->dwType = dwType;
penvar->szValueName = CloneString (szTemp);
penvar->szValue = CloneString (pszValue);
penvar->szExpValue = CloneString (pszString);
item.mask = LVIF_TEXT | LVIF_PARAM;
item.iItem = (dwIndex - 1);
item.iSubItem = 0;
item.pszText = penvar->szValueName;
item.lParam = (LPARAM) penvar;
n = SendMessage (hwndTemp, LVM_INSERTITEM, 0, (LPARAM) &item);
if (n != -1) {
item.mask = LVIF_TEXT;
item.iItem = n;
item.iSubItem = 1;
item.pszText = penvar->szExpValue;
SendMessage (hwndTemp, LVM_SETITEMTEXT, n, (LPARAM) &item);
}
UserLoop:
// Reset vars for next iteration
dwBufz = ARRAYSIZE(szTemp);
dwValz = BUFZ * SIZEOF(TCHAR);
}
RegCloseKey (hkeyEnv);
}
else
{
// Report opening USER Environment key
if (MsgBoxParam (hDlg, SYSTEM+8, INITS+1,
MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
{
// Free allocated memory since we are returning from here
MemFree ((LPVOID)hKey);
MemFree (pszString);
HourGlass (FALSE);
return FALSE;
}
}
//
// Select the first items in the listviews
// It is important to set the User listview first, and
// then the system. When the system listview is set,
// we will receive a LVN_ITEMCHANGED notification and
// clear the focus in the User listview. But when someone
// tabs to the control the arrow keys will work correctly.
//
item.mask = LVIF_STATE;
item.iItem = 0;
item.iSubItem = 0;
item.state = LVIS_SELECTED | LVIS_FOCUSED;
item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_USERVARS,
LVM_SETITEMSTATE, 0, (LPARAM) &item);
SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_SYSVARS,
LVM_SETITEMSTATE, 0, (LPARAM) &item);
// EM_LIMITTEXT of VARIABLE and VALUE editbox
SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_VAR, EM_LIMITTEXT, MAX_PATH-1, 0L);
SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_VALUE, EM_LIMITTEXT, MAX_VALUE_LEN-1, 0L);
// Remove text from Editboxes
SetDlgItemText (hDlg, IDC_ENVVAR_SYS_VAR, g_szNull);
SetDlgItemText (hDlg, IDC_ENVVAR_SYS_VALUE, g_szNull);
EnableWindow (GetDlgItem (hDlg, IDC_ENVVAR_SYS_SETUV), FALSE);
EnableWindow (GetDlgItem (hDlg, IDC_ENVVAR_SYS_DELUV), FALSE);
MemFree ((LPVOID)hKey);
MemFree (pszString);
// Set extended LV style for whole line selection
SendDlgItemMessage(hDlg, IDC_ENVVAR_SYS_LB_SYSVARS, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
SendDlgItemMessage(hDlg, IDC_ENVVAR_SYS_LB_USERVARS, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
HourGlass (FALSE);
///////////////////
// Return succes //
///////////////////
return TRUE;
}
//*************************************************************
//
// EnvVarsDlgProc()
//
// Purpose: Dialog box procedure for Environment Variables tab
//
// Parameters: hDlg - handle to the dialog box
// uMsg - window message
// wParam - wParam
// lParam - lParam
//
// Return: TRUE if message was processed
// FALSE if not
//
// Comments:
//
// History: Date Author Comment
// 11/21/95 ericflo Created
//
//*************************************************************
BOOL APIENTRY EnvVarsDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
if (!InitEnvVarsDlg(hDlg)) {
EndDialog (hDlg, 0);
}
break;
case WM_NOTIFY:
switch (((NMHDR FAR*)lParam)->code)
{
case LVN_ITEMCHANGED:
EVDoItemChanged (hDlg, (int)wParam);
break;
case LVN_COLUMNCLICK:
EVDoItemChanged (hDlg, (int) wParam);
break;
case NM_SETFOCUS:
if (wParam == IDC_ENVVAR_SYS_LB_USERVARS) {
bUserVars = TRUE;
} else {
bUserVars = FALSE;
}
EVDoItemChanged (hDlg, (int) wParam);
break;
case PSN_APPLY:
{
PSHNOTIFY *lpNotify = (PSHNOTIFY *) lParam;
EVSave(hDlg);
SetWindowLong (hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
return TRUE;
}
case PSN_RESET:
SetWindowLong (hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
return TRUE;
default:
return FALSE;
}
break;
case WM_COMMAND:
EVDoCommand(hDlg, (HWND)lParam, LOWORD(wParam), HIWORD(wParam));
break;
case WM_DESTROY:
EVCleanUp (hDlg);
break;
case WM_HELP: // F1
WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (DWORD) (LPSTR) aEnvVarsHelpIds);
break;
case WM_CONTEXTMENU: // right mouse click
WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU, (DWORD) (LPSTR) aEnvVarsHelpIds);
break;
default:
return FALSE;
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////
// EVDoCommand
//
// Process commands for the Environment Vars page of the system app
//
// History:
// 10-Jan-1996 JonPa Started it
// 18-Jan-1996 EricFlo Finished it
////////////////////////////////////////////////////////////////////////////
void EVDoCommand(HWND hDlg, HWND hwndCtl, int idCtl, int iNotify )
{
TCHAR szTemp2[MAX_PATH];
int i, n;
TCHAR *bBuffer;
TCHAR *pszTemp;
LPTSTR pszString;
HWND hwndTemp;
ENVARS *penvar;
LV_ITEM item;
switch (idCtl) {
case IDC_ENVVAR_SYS_VALUE:
case IDC_ENVVAR_SYS_VAR:
// IF focus is being set to one of these controls, enable
// new buttons as appropriate
// ELSE allow "Enter" key to simply choose the IDOK button
// If the USER activates or clicks in either Variable or Value
// editbox, then change "Set" to the DefPushbutton
if (iNotify == EN_SETFOCUS)
{
if (GetDlgItemText (hDlg, IDC_ENVVAR_SYS_VAR, szTemp2, ARRAYSIZE(szTemp2)))
{
EnableWindow (GetDlgItem (hDlg, IDC_ENVVAR_SYS_SETUV), TRUE);
EnableWindow (GetDlgItem (hDlg, IDC_ENVVAR_SYS_DELUV), TRUE);
SetDefButton (hDlg, IDC_ENVVAR_SYS_SETUV);
}
else
{
EnableWindow (GetDlgItem (hDlg, IDC_ENVVAR_SYS_SETUV), FALSE);
EnableWindow (GetDlgItem (hDlg, IDC_ENVVAR_SYS_DELUV), FALSE);
SetDefButton (GetParent(hDlg), IDOK);
}
}
else if (iNotify == EN_KILLFOCUS)
{
SetDefButton (GetParent(hDlg), IDOK);
}
break;
case IDC_ENVVAR_SYS_DELUV:
// Delete listbox entry that matches value in IDC_ENVVAR_SYS_VAR
// If found, delete entry else ignore
GetDlgItemText (hDlg, IDC_ENVVAR_SYS_VAR, szTemp2, ARRAYSIZE(szTemp2));
if (szTemp2[0] == TEXT('\0'))
break;
// Determine which Listbox is active (SYSTEM or USER vars)
hwndTemp = GetDlgItem (hDlg, bUserVars ? IDC_ENVVAR_SYS_LB_USERVARS :
IDC_ENVVAR_SYS_LB_SYSVARS);
n = FindVar (hwndTemp, szTemp2);
if (n != -1)
{
// Free existing strings (listbox and ours)
item.mask = LVIF_PARAM;
item.iItem = n;
item.iSubItem = 0;
if (SendMessage (hwndTemp, LVM_GETITEM, 0, (LPARAM) &item)) {
penvar = (ENVARS *) item.lParam;
} else {
penvar = NULL;
}
if (penvar) {
MemFree (penvar->szValueName);
MemFree (penvar->szValue);
MemFree (penvar->szExpValue);
MemFree ((LPVOID) penvar);
}
SendMessage (hwndTemp, LVM_DELETEITEM, n, 0L);
PropSheet_Changed(GetParent(hDlg), hDlg);
// Fix selection state in listview
if (n > 0) {
n--;
}
item.mask = LVIF_STATE;
item.iItem = n;
item.iSubItem = 0;
item.state = LVIS_SELECTED | LVIS_FOCUSED;
item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_USERVARS,
LVM_SETITEMSTATE, n, (LPARAM) &item);
// Remove text from Editboxes
SetDlgItemText (hDlg, IDC_ENVVAR_SYS_VAR, g_szNull);
SetDlgItemText (hDlg, IDC_ENVVAR_SYS_VALUE, g_szNull);
// Disable useless controls
EnableWindow (GetDlgItem (hDlg, IDC_ENVVAR_SYS_SETUV), FALSE);
EnableWindow (GetDlgItem (hDlg, IDC_ENVVAR_SYS_DELUV), FALSE);
// Reset OK as "DefPushbutton" and re-enable keybd input
SetDefButton (GetParent(hDlg), IDOK);
SetFocus (GetDlgItem (GetParent(hDlg), IDOK));
}
break;
case IDC_ENVVAR_SYS_SETUV:
// Set the Environment variable in IDC_ENVVAR_SYS_VAR
// Also add or change the registry entry
GetDlgItemText (hDlg, IDC_ENVVAR_SYS_VAR, szTemp2, ARRAYSIZE(szTemp2));
// Strip trailing whitespace from end of Env Variable
i = lstrlen(szTemp2) - 1;
while (i >= 0)
{
if (_istspace(szTemp2[i]))
szTemp2[i--] = TEXT('\0');
else
break;
}
if (szTemp2[0] == TEXT('\0'))
break;
bBuffer = (TCHAR *) MemAlloc (LPTR, BUFZ * sizeof(TCHAR));
pszString = (LPTSTR) MemAlloc (LPTR, BUFZ * sizeof(TCHAR));
GetDlgItemText (hDlg, IDC_ENVVAR_SYS_VALUE, bBuffer, BUFZ);
// Determine which Listbox is active (SYSTEM or USER vars)
hwndTemp = GetDlgItem (hDlg, bUserVars ? IDC_ENVVAR_SYS_LB_USERVARS :
IDC_ENVVAR_SYS_LB_SYSVARS);
n = FindVar (hwndTemp, szTemp2);
if (n != -1)
{
// Free existing strings (listview and ours)
item.mask = LVIF_PARAM;
item.iItem = n;
item.iSubItem = 0;
if (SendMessage (hwndTemp, LVM_GETITEM, 0, (LPARAM) &item)) {
penvar = (ENVARS *) item.lParam;
} else {
penvar = NULL;
}
if (penvar) {
MemFree (penvar->szValueName);
MemFree (penvar->szValue);
MemFree (penvar->szExpValue);
}
SendMessage (hwndTemp, LVM_DELETEITEM, n, 0L);
}
else
{
// Get some storage for new Env Var
penvar = (ENVARS *) MemAlloc (LPTR, sizeof(ENVARS));
}
// If there are two '%' chars in string, then this is a
// REG_EXPAND_SZ style environment string
pszTemp = _tcspbrk (bBuffer, TEXT("%"));
if (pszTemp && _tcspbrk (pszTemp, TEXT("%")))
penvar->dwType = REG_EXPAND_SZ;
else
penvar->dwType = REG_SZ;
ExpandEnvironmentStrings (bBuffer, pszString, BUFZ);
penvar->szValueName = CloneString (szTemp2);
penvar->szValue = CloneString (bBuffer);
penvar->szExpValue = CloneString (pszString);
item.mask = LVIF_TEXT | LVIF_PARAM;
item.iItem = ListView_GetItemCount(hwndTemp);
item.iSubItem = 0;
item.pszText = penvar->szValueName;
item.lParam = (LPARAM) penvar;
n = SendMessage (hwndTemp, LVM_INSERTITEM, 0, (LPARAM) &item);
if (n != -1) {
item.mask = LVIF_TEXT;
item.iItem = n;
item.iSubItem = 1;
item.pszText = penvar->szExpValue;
SendMessage (hwndTemp, LVM_SETITEMTEXT, n, (LPARAM) &item);
PropSheet_Changed(GetParent(hDlg), hDlg);
// Set selection state to new item
ClearAllSelections(hwndTemp);
item.mask = LVIF_STATE;
item.iItem = n;
item.iSubItem = 0;
item.state = LVIS_SELECTED | LVIS_FOCUSED;
item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
SendDlgItemMessage (hDlg, IDC_ENVVAR_SYS_LB_USERVARS,
LVM_SETITEMSTATE, n, (LPARAM) &item);
}
// Remove text from Editboxes after add
SetDlgItemText (hDlg, IDC_ENVVAR_SYS_VAR, g_szNull);
SetDlgItemText (hDlg, IDC_ENVVAR_SYS_VALUE, g_szNull);
MemFree (bBuffer);
MemFree (pszString);
// Set user input back to VARIABLE field
SetFocus (GetDlgItem (hDlg, IDC_ENVVAR_SYS_VAR));
break;
default:
break;
}
}
void ClearAllSelections (HWND hCtrl)
{
int i,n;
LV_ITEM item;
item.mask = LVIF_STATE;
item.iSubItem = 0;
item.state = 0;
item.stateMask = LVIS_FOCUSED;
n = SendMessage (hCtrl, LVM_GETITEMCOUNT, 0, 0L);
if (n != LB_ERR)
{
for (i = 0; i < n; i++)
{
item.iItem = i;
SendMessage (hCtrl, LVM_SETITEMSTATE, i, (LPARAM) &item);
}
}
}
int GetSelectedItem (HWND hCtrl)
{
int i, n;
n = SendMessage (hCtrl, LVM_GETITEMCOUNT, 0, 0L);
if (n != LB_ERR)
{
for (i = 0; i < n; i++)
{
if (SendMessage (hCtrl, LVM_GETITEMSTATE,
i, (LPARAM) LVIS_SELECTED) == LVIS_SELECTED) {
return i;
}
}
}
return -1;
}
////////////////////////////////////////////////////////////////////////////
// EVDoItemChanged
//
// Process notify's for the Environment Vars page of the system app
//
// History:
// 19-Jan-1996 EricFlo Finished it
////////////////////////////////////////////////////////////////////////////
void EVDoItemChanged(HWND hDlg, int idCtl)
{
int selection;
HWND hwndTemp;
ENVARS *penvar;
LV_ITEM item;
switch (idCtl) {
case IDC_ENVVAR_SYS_LB_SYSVARS:
if (!bEditSystemVars)
return;
/* Fall through */
case IDC_ENVVAR_SYS_LB_USERVARS:
hwndTemp = GetDlgItem (hDlg, idCtl);
//
// Clear the selection from the other listbox
// so the user doens't have to figure out which
// one he is editing
//
ClearAllSelections (GetDlgItem(hDlg,
(idCtl == IDC_ENVVAR_SYS_LB_USERVARS) ?
IDC_ENVVAR_SYS_LB_SYSVARS : IDC_ENVVAR_SYS_LB_USERVARS));
selection = GetSelectedItem (hwndTemp);
if (selection != -1)
{
item.mask = LVIF_PARAM;
item.iItem = selection;
item.iSubItem = 0;
if (SendMessage (hwndTemp, LVM_GETITEM, 0, (LPARAM) &item)) {
penvar = (ENVARS *) item.lParam;
} else {
penvar = NULL;
}
if (penvar) {
SetDlgItemText (hDlg, IDC_ENVVAR_SYS_VAR, penvar->szValueName);
SetDlgItemText (hDlg, IDC_ENVVAR_SYS_VALUE, penvar->szValue);
// Enable DELETE button
EnableWindow (GetDlgItem (hDlg, IDC_ENVVAR_SYS_DELUV), TRUE);
}
}
else
{
// Else we are only deselecting an item so...
// simply remove all text from Editboxes
SetDlgItemText (hDlg, IDC_ENVVAR_SYS_VAR, g_szNull);
SetDlgItemText (hDlg, IDC_ENVVAR_SYS_VALUE, g_szNull);
// Disable buttons
EnableWindow (GetDlgItem (hDlg, IDC_ENVVAR_SYS_DELUV), FALSE);
EnableWindow (GetDlgItem (hDlg, IDC_ENVVAR_SYS_SETUV), FALSE);
}
break;
}
}
////////////////////////////////////////////////////////////////////////////
// SetLBWidthEx
//
// Set the width of the listbox, in pixels, acording to the size of the
// string passed in.
//
// Note: this function is also used by the Virtual Memory dialog
//
// History:
// 11-Jan-1996 JonPa Created from SetGenLBWidth
////////////////////////////////////////////////////////////////////////////
DWORD SetLBWidthEx (HWND hwndLB, LPTSTR szBuffer, DWORD cxCurWidth, DWORD cxExtra)
{
HDC hDC;
SIZE Size;
LONG cx;
HFONT hfont, hfontOld;
// Get the new Win4.0 thin dialog font
hfont = (HFONT)SendMessage(hwndLB, WM_GETFONT, 0, 0);
hDC = GetDC(hwndLB);
// if we got a font back, select it in this clean hDC
if (hfont != NULL)
hfontOld = SelectObject(hDC, hfont);
// If cxExtra is 0, then give our selves a little breathing space.
if (cxExtra == 0) {
GetTextExtentPoint(hDC, TEXT("1234"), 4 /* lstrlen("1234") */, &Size);
cxExtra = Size.cx;
}
// Set scroll width of listbox
GetTextExtentPoint(hDC, szBuffer, lstrlen(szBuffer), &Size);
Size.cx += cxExtra;
// Get the name length and adjust the longest name
if ((DWORD) Size.cx > cxCurWidth)
{
cxCurWidth = Size.cx;
SendMessage (hwndLB, LB_SETHORIZONTALEXTENT, (DWORD)Size.cx, 0L);
}
// retstore the original font if we changed it
if (hfont != NULL)
SelectObject(hDC, hfontOld);
ReleaseDC(NULL, hDC);
return cxCurWidth;
}
/*************************************************************************\
*
* LPTSTR CloneString( LPTSTR pszSrc );
*
* Makes a copy of a string. The new string is copyied to a newly alloced
* buffer and that buffer is returned
*
\*************************************************************************/
LPTSTR CloneString( LPTSTR pszSrc ) {
LPTSTR pszDst = NULL;
if (pszSrc != NULL) {
pszDst = MemAlloc(LMEM_FIXED, (lstrlen(pszSrc)+1) * SIZEOF(TCHAR));
if (pszDst) {
lstrcpy( pszDst, pszSrc );
}
}
return pszDst;
}
////////////////////////////////////////////////////////////////////////////
// FindVar
//
// Find the USER Environment variable that matches passed string
// and return its listview index or -1
//
////////////////////////////////////////////////////////////////////////////
int FindVar (HWND hwndLV, LPTSTR szVar)
{
LV_FINDINFO FindInfo;
FindInfo.flags = LVFI_STRING;
FindInfo.psz = szVar;
return (SendMessage (hwndLV, LVM_FINDITEM, (WPARAM) -1, (LPARAM) &FindInfo));
}
////////////////////////////////////////////////////////////////////////////
// EVSave
//
// Saves the environment variables
//
// History:
// 19-Jan-1996 EricFlo Wrote it
////////////////////////////////////////////////////////////////////////////
void EVSave(HWND hDlg)
{
TCHAR szTemp[MAX_PATH];
int selection;
int i, n;
TCHAR *bBuffer;
TCHAR *pszTemp;
LPTSTR pszString;
HWND hwndTemp;
ENVARS *penvar;
REGVAL *prvFirst;
REGVAL *prvRegVal;
HKEY hkeyEnv;
DWORD dwBufz, dwIndex, dwType;
LV_ITEM item;
HourGlass (TRUE);
/////////////////////////////////////////////////////////////////
// Set all new USER environment variables to current values
// but delete all old environment variables first
/////////////////////////////////////////////////////////////////
if (RegOpenKeyEx (HKEY_CURRENT_USER, szUserEnv, 0,
KEY_READ | KEY_WRITE, &hkeyEnv)
== ERROR_SUCCESS)
{
dwBufz = ARRAYSIZE(szTemp) * sizeof(TCHAR);
dwIndex = 0;
// Delete all values of type REG_SZ & REG_EXPAND_SZ under key
// First: Make a linked list of all USER Env string vars
prvFirst = (REGVAL *) NULL;
while (!RegEnumValue(hkeyEnv,
dwIndex++, // Index'th value name/data
szTemp, // Ptr to ValueName buffer
&dwBufz, // Size of ValueName buffer
NULL, // Title index return
&dwType, // Type code of entry
NULL, // Ptr to ValueData buffer
NULL)) // Size of ValueData buffer
{
if ((dwType != REG_SZ) && (dwType != REG_EXPAND_SZ))
continue;
if (prvFirst)
{
prvRegVal->prvNext = (REGVAL *) MemAlloc (LPTR, sizeof(REGVAL));
prvRegVal = prvRegVal->prvNext;
}
else // First time thru
{
prvFirst = prvRegVal = (REGVAL *) MemAlloc (LPTR, sizeof(REGVAL));
}
prvRegVal->prvNext = NULL;
prvRegVal->szValueName = CloneString (szTemp);
// Reset vars for next call
dwBufz = ARRAYSIZE(szTemp) * sizeof(TCHAR);
}
// Now traverse the list, deleting them all
prvRegVal = prvFirst;
while (prvRegVal)
{
RegDeleteValue (hkeyEnv, prvRegVal->szValueName);
MemFree (prvRegVal->szValueName);
prvFirst = prvRegVal;
prvRegVal = prvRegVal->prvNext;
MemFree ((LPVOID) prvFirst);
}
///////////////////////////////////////////////////////////////
// Set all new USER environment variables to current values
///////////////////////////////////////////////////////////////
hwndTemp = GetDlgItem (hDlg, IDC_ENVVAR_SYS_LB_USERVARS);
if ((n = SendMessage (hwndTemp, LVM_GETITEMCOUNT, 0, 0L)) != LB_ERR)
{
item.mask = LVIF_PARAM;
item.iSubItem = 0;
for (i = 0; i < n; i++)
{
item.iItem = i;
if (SendMessage (hwndTemp, LVM_GETITEM, 0, (LPARAM) &item)) {
penvar = (ENVARS *) item.lParam;
} else {
penvar = NULL;
}
if (penvar) {
if (RegSetValueEx (hkeyEnv,
penvar->szValueName,
0L,
penvar->dwType,
(LPBYTE) penvar->szValue,
(lstrlen (penvar->szValue)+1) * sizeof(TCHAR)))
{
// Report error trying to set registry values
if (MsgBoxParam (hDlg, SYSTEM+9, INITS+1,
MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
break;
}
}
}
}
RegFlushKey (hkeyEnv);
RegCloseKey (hkeyEnv);
}
else
{
// Report opening USER Environment key
if (MsgBoxParam (hDlg, SYSTEM+8, INITS+1,
MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
goto Exit;
}
/////////////////////////////////////////////////////////////////
// Set all new SYSTEM environment variables to current values
// but delete all old environment variables first
/////////////////////////////////////////////////////////////////
if (!bEditSystemVars)
goto SkipSystemVars;
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
szSysEnv,
0,
KEY_READ | KEY_WRITE,
&hkeyEnv)
== ERROR_SUCCESS)
{
dwBufz = ARRAYSIZE(szTemp) * sizeof(TCHAR);
dwIndex = 0;
// Delete all values of type REG_SZ & REG_EXPAND_SZ under key
// First: Make a linked list of all Env string vars
prvFirst = (REGVAL *) NULL;
while (!RegEnumValue(hkeyEnv,
dwIndex++, // Index'th value name/data
szTemp, // Ptr to ValueName buffer
&dwBufz, // Size of ValueName buffer
NULL, // Title index return
&dwType, // Type code of entry
NULL, // Ptr to ValueData buffer
NULL)) // Size of ValueData buffer
{
if ((dwType != REG_SZ) && (dwType != REG_EXPAND_SZ))
continue;
if (prvFirst)
{
prvRegVal->prvNext = (REGVAL *) MemAlloc (LPTR, sizeof(REGVAL));
prvRegVal = prvRegVal->prvNext;
}
else // First time thru
{
prvFirst = prvRegVal = (REGVAL *) MemAlloc (LPTR, sizeof(REGVAL));
}
prvRegVal->prvNext = NULL;
prvRegVal->szValueName = CloneString (szTemp);
// Reset vars for next call
dwBufz = ARRAYSIZE(szTemp) * sizeof(TCHAR);
}
// Now traverse the list, deleting them all
prvRegVal = prvFirst;
while (prvRegVal)
{
RegDeleteValue (hkeyEnv, prvRegVal->szValueName);
MemFree (prvRegVal->szValueName);
prvFirst = prvRegVal;
prvRegVal = prvRegVal->prvNext;
MemFree ((LPVOID) prvFirst);
}
///////////////////////////////////////////////////////////////
// Set all new SYSTEM environment variables to current values
///////////////////////////////////////////////////////////////
hwndTemp = GetDlgItem (hDlg, IDC_ENVVAR_SYS_LB_SYSVARS);
if ((n = SendMessage (hwndTemp, LVM_GETITEMCOUNT, 0, 0L)) != LB_ERR)
{
item.mask = LVIF_PARAM;
item.iSubItem = 0;
for (i = 0; i < n; i++)
{
item.iItem = i;
if (SendMessage (hwndTemp, LVM_GETITEM, 0, (LPARAM) &item)) {
penvar = (ENVARS *) item.lParam;
} else {
penvar = NULL;
}
if (penvar) {
if (RegSetValueEx (hkeyEnv,
penvar->szValueName,
0L,
penvar->dwType,
(LPBYTE) penvar->szValue,
(lstrlen (penvar->szValue)+1) * sizeof(TCHAR)))
{
// Report error trying to set registry values
if (MsgBoxParam (hDlg, SYSTEM+9, INITS+1,
MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
break;
}
}
}
}
RegFlushKey (hkeyEnv);
RegCloseKey (hkeyEnv);
}
else
{
// Report opening SYSTEM Environment key
if (MsgBoxParam (hDlg, SYSTEM+21, INITS+1,
MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
goto Exit;
}
SkipSystemVars:
// Send public message announcing change to Environment
SendMessageTimeout( (HWND)-1, WM_WININICHANGE, 0L, (LONG)szUserEnv,
SMTO_ABORTIFHUNG, 1000, NULL );
Exit:
HourGlass (FALSE);
}
////////////////////////////////////////////////////////////////////////////
// EVCleanUp
//
// Frees memory allocated for environment variables
//
// History:
// 19-Jan-1996 EricFlo Wrote it
////////////////////////////////////////////////////////////////////////////
void EVCleanUp (HWND hDlg)
{
int i, n;
HWND hwndTemp;
ENVARS *penvar;
LV_ITEM item;
//
// Free alloc'd strings and memory for UserEnvVars list box items
//
hwndTemp = GetDlgItem (hDlg, IDC_ENVVAR_SYS_LB_USERVARS);
n = SendMessage (hwndTemp, LVM_GETITEMCOUNT, 0, 0L);
item.mask = LVIF_PARAM;
item.iSubItem = 0;
for (i = 0; i < n; i++) {
item.iItem = i;
if (SendMessage (hwndTemp, LVM_GETITEM, 0, (LPARAM) &item)) {
penvar = (ENVARS *) item.lParam;
} else {
penvar = NULL;
}
if (penvar) {
MemFree (penvar->szValueName);
MemFree (penvar->szValue);
MemFree (penvar->szExpValue);
MemFree ((LPVOID) penvar);
}
}
//
// Free alloc'd strings and memory for SysEnvVars list box items
//
hwndTemp = GetDlgItem (hDlg, IDC_ENVVAR_SYS_LB_SYSVARS);
n = SendMessage (hwndTemp, LVM_GETITEMCOUNT, 0, 0L);
for (i = 0; i < n; i++) {
item.iItem = i;
if (SendMessage (hwndTemp, LVM_GETITEM, 0, (LPARAM) &item)) {
penvar = (ENVARS *) item.lParam;
} else {
penvar = NULL;
}
if (penvar) {
MemFree (penvar->szValueName);
MemFree (penvar->szValue);
MemFree (penvar->szExpValue);
MemFree ((LPVOID) penvar);
}
}
}