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.
 
 
 
 
 
 

964 lines
18 KiB

/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
Environ.c
Abstract:
This module contains support for the Environment dialog.
Author:
David J. Gilman (davegi) 3-Dec-1992
Gregg R. Acheson (GreggA) 5-Sep-1993
Environment:
User Mode
--*/
#include "dialogs.h"
#include "environ.h"
#include "dlgprint.h"
#include "strresid.h"
#include "registry.h"
#include "winmsd.h"
#include <string.h>
#include <tchar.h>
extern HKEY _hKeyLocalMachine;
//
// System environment variables.
//
MakeKey(
_SystemEnvironKey,
HKEY_LOCAL_MACHINE,
TEXT( "System\\CurrentControlSet\\Control\\Session Manager\\Environment" ),
0,
NULL
);
//
// Per user environment variables.
//
MakeKey(
_UserEnvironKey,
HKEY_CURRENT_USER,
TEXT( "Environment" ),
0,
NULL
);
//
// Environment value and variable.
//
typedef
struct
_ENV_VAR {
LPWSTR Variable;
LPWSTR Value;
} ENV_VAR, *LPENV_VAR;
//
// CurrentEnvVar is the current environment variable in the enumeration
// supported by FindFirstEnvironmentVariable and FindNextEnvironmentVariable.
//
LPTSTR
CurrentEnvVar;
//
// hRegEnvironKey is the Registry key handle that is used to support the
// enumeration of environment variables in the Registry.
//
HREGKEY
hRegEnvironKey;
//
// Internal function prototypes.
//
BOOL
FillEnvironmentListBox(
IN HWND hWnd,
IN LPKEY Key
);
LPENV_VAR
FindFirstEnvironmentVariableW(
);
LPENV_VAR
FindFirstRegistryEnvironmentVariableW(
);
LPENV_VAR
FindNextEnvironmentVariableW(
);
LPENV_VAR
FindNextRegistryEnvironmentVariableW(
);
BOOL
DoEnvironReport(
LPKEY Key
);
BOOL
InitializeEnvironmentTab(
HWND hWnd
);
BOOL
EnvDisplayList(
IN HWND hWnd,
IN UINT iDisplayOption
);
DWORD
WinMSDExpandEnvironmentStrings(
LPCWSTR lpSrc,
LPWSTR lpDst,
DWORD nSize
);
BOOL
FillEnvironmentListBox(
IN HWND hWnd,
IN LPKEY Key
)
/*++
Routine Description:
FillEnvironmentListBox fills the list box referred to by the supplied
window handle and control id with enviornment variables and values. The
environment comes from either the location specified by the supplied key or
from the process if the key is NULL.
Arguments:
hWnd = Supplies the window handle for the window that contains
the list box.
Key - Supplies a pointer to a registry KEY object that describes
the location of the environment.
Return Value:
BOOL - Returns TRUE if the list box was succesfully filled with the
environment, FALSE otherwise.
--*/
{
BOOL Success;
LPENV_VAR EnvVar;
LPENV_VAR ( *NextEnvVarFunc )( );
LV_ITEM lvI;
UINT index = 0;
//
// If the supplied Key is NULL get the environment variables from the
// current process, otherwise get them from the supplied Registry key.
//
if( Key == NULL ) {
EnvVar = FindFirstEnvironmentVariableW( );
NextEnvVarFunc = FindNextEnvironmentVariableW;
} else {
EnvVar = FindFirstRegistryEnvironmentVariableW( Key );
NextEnvVarFunc = FindNextRegistryEnvironmentVariableW;
}
//
// For each environment variable, initialize the CLB_ROW and CLB_STRING
// object and add each row's column data.
//
while( EnvVar ) {
// Add the service name and its state to the ListView. Store a
// pointer to the service details in the lParam.
lvI.mask = LVIF_TEXT;
lvI.iItem = index++;
lvI.iSubItem = 0;
lvI.pszText= EnvVar->Variable;
lvI.cchTextMax = 1024;
Success = ListView_InsertItem( hWnd, &lvI);
ListView_SetItemText( hWnd, Success, 1, EnvVar->Value);
//
// Get the next environment variable.
//
EnvVar = NextEnvVarFunc( );
}
return TRUE;
}
LPENV_VAR
FindFirstEnvironmentVariableW(
)
/*++
Routine Description:
This routine starts the enumeration of this process' environment variables
by initializing the CurrentEnvVar variable. It then returns the first
environment varaiable in the enumeration.
Arguments:
None.
Return Value:
LPENV_VAR - Returns a pointer to a static ENV_VAR object containing the
first environment variable in the list, NULL if there is none.
--*/
{
//
// Initialize the current environment variable.
//
CurrentEnvVar = GetEnvironmentStrings( );
DbgPointerAssert( CurrentEnvVar );
if( CurrentEnvVar == NULL ) {
return NULL;
}
//
// Return the first environmenr variable.
//
return FindNextEnvironmentVariableW( );
}
LPENV_VAR
FindFirstRegistryEnvironmentVariableW(
IN LPKEY Key
)
/*++
Routine Description:
This routine starts the enumeration of the environment variables at the
location specified by the supplied Registry KEY object.
Arguments:
None.
Return Value:
LPENV_VAR - Returns a pointer to a static ENV_VAR object containing the
first environment variable in the list, NULL if there is none.
--*/
{
//
// Initialize the current environment variable.
//
hRegEnvironKey = OpenRegistryKey( Key );
DbgHandleAssert( hRegEnvironKey );
if( hRegEnvironKey == NULL ) {
return NULL;
}
//
// Return the first environmenr variable.
//
return FindNextRegistryEnvironmentVariableW( );
}
LPENV_VAR
FindNextEnvironmentVariableW(
)
/*++
Routine Description:
FindNextEnvironmentVariable continues an enumeration that has been
initialized by a previous call to FindFirstEnvironmentVariable. Since the
environment strings are only available in ANSI, this routine converts them
to Unicode before returning. Further it sets up for the next iteratuion by
adjusting the currency pointer.
Arguments:
None.
Return Value:
LPENV_VAR - Returns a pointer to a static ENV_VAR object containing the next
environment variable in the list, NULL if there are none.
--*/
{
static
WCHAR Buffer[ 2048 ];
static
ENV_VAR EnvVar;
//
// If the current environment variable pointer points to an empty string
// return NULL.
//
if( *CurrentEnvVar == TEXT('\0') ) {
return NULL;
}
lstrcpyn(Buffer, CurrentEnvVar,2048);
if ( lstrlen(Buffer) >= 2048){
Buffer[(2048*2)-2]=L'\0';
}
//
// Update the current environment variable pointer to point to the
// variable.
//
CurrentEnvVar += _tcslen( CurrentEnvVar ) + 1;
//
// Parse the buffer into an ENV_VAR object. The first '=' sign seen from
// the end of the buffer is the seperator. The search is done in reverse
// because of the special current directory environment variablles
// (e.g. =c:).
//
EnvVar.Variable = Buffer;
EnvVar.Value = wcsrchr( Buffer, '=' ) + 1;
EnvVar.Variable[ EnvVar.Value - EnvVar.Variable - 1 ] = L'\0';
return &EnvVar;
}
LPENV_VAR
FindNextRegistryEnvironmentVariableW(
)
/*++
Routine Description:
FindNextRegistryEnvironmentVariable continues an enumeration that has been
initialized by a previous call to FindFirstRegistryEnvironmentVariable. For
each environment variable that it finds it converts it to two simple
strings, the variable and the value.
Arguments:
None.
Return Value:
LPENV_VAR - Returns a pointer to a static ENV_VAR object containing the next
environment variable in the list, NULL if there are none.
--*/
{
BOOL Success;
DWORD Length;
static
WCHAR Buffer[ 2048 ];
static
ENV_VAR EnvVar;
//
// If there is another environment variable...
//
if( QueryNextValue( hRegEnvironKey )) {
//
// Remember the environment variable's name.
//
EnvVar.Variable = hRegEnvironKey->ValueName;
switch( hRegEnvironKey->Type ) {
case REG_SZ:
//
// Remember the environment variable's value.
//
EnvVar.Value = ( LPWSTR ) hRegEnvironKey->Data;
break;
case REG_EXPAND_SZ:
{
//
// Replace the variable portion of the environment variable by
// expanding into the static buffer.
//
EnvVar.Value = Buffer;
Length = WinMSDExpandEnvironmentStrings(
( LPTSTR ) hRegEnvironKey->Data,
Buffer,
2048
);
DbgAssert( Length <= 2048);
break;
}
default:
DbgAssert( FALSE );
}
//
// Return the current environment variable.
//
return &EnvVar;
} else {
//
// There are no more environment variables so close the key and
// return NULL.
//
Success = CloseRegistryKey( hRegEnvironKey );
DbgAssert( Success );
return NULL;
}
DbgAssert( FALSE );
}
BOOL
EnvironmentTabProc(
IN HWND hWnd,
IN UINT message,
IN WPARAM wParam,
IN LPARAM lParam
)
/*++
Routine Description:
Display the three (system, user and process) environment variable lists.
Arguments:
Standard DLGPROC entry.
Return Value:
BOOL - Depending on input message and processing options.
--*/
{
switch( message ) {
case WM_INITDIALOG:
{
InitializeEnvironmentTab( hWnd );
break;
}
case WM_COMMAND:
switch( LOWORD( wParam )) {
case IDC_PUSH_SHOW_SYSTEM:
case IDC_PUSH_SHOW_USER:
EnvDisplayList( GetDlgItem( hWnd, IDC_LV_ENV ), LOWORD( wParam ) );
break;
}
break;
}
//
// Handle unhandled messages.
//
return FALSE;
}
BOOL
BuildEnvironmentReport(
IN HWND hWnd,
IN UINT iDetailLevel
)
/*++
Routine Description:
Formats and adds Environment Data to the report buffer.
Arguments:
ReportBuffer - Array of pointers to lines that make up the report.
NumReportLines - Running count of the number of lines in the report..
Return Value:
BOOL - TRUE if report is build successfully, FALSE otherwise.
--*/
{
KEY SystemEnvironKey,
UserEnvironKey;
AddLineToReport( 2, RFO_SKIPLINE, NULL, NULL );
AddLineToReport( 0, RFO_SINGLELINE, (LPTSTR) GetString( IDS_ENVIRON_REPORT ), NULL );
AddLineToReport( 0, RFO_SEPARATOR, NULL, NULL );
AddLineToReport( 2, RFO_SKIPLINE, NULL, NULL );
AddLineToReport( 0, RFO_SINGLELINE, (LPTSTR) GetString( IDS_SYSTEM_VARS ), NULL );
CopyMemory(
&SystemEnvironKey,
&_SystemEnvironKey,
sizeof( SystemEnvironKey )
);
DoEnvironReport(&SystemEnvironKey);
if( _fIsRemote == FALSE ){
AddLineToReport( 2, RFO_SKIPLINE, NULL, NULL );
AddLineToReport( 0, RFO_SINGLELINE, (LPTSTR) GetString( IDS_CURRENT_USERS_VARS ), NULL );
CopyMemory(
&UserEnvironKey,
&_UserEnvironKey,
sizeof( UserEnvironKey)
);
DoEnvironReport(&UserEnvironKey);
}
return TRUE;
}
BOOL
DoEnvironReport(
LPKEY Key
)
{
LPENV_VAR EnvVar;
LPENV_VAR ( *NextEnvVarFunc ) ( );
TCHAR OutputBuffer [2048];
//
// If the supplied Key is NULL get the environment variables from the
// current process, otherwise get them from the supplied Registry key.
//
if( Key == NULL ) {
EnvVar = FindFirstEnvironmentVariableW( );
NextEnvVarFunc = FindNextEnvironmentVariableW;
} else {
EnvVar = FindFirstRegistryEnvironmentVariableW( Key );
NextEnvVarFunc = FindNextRegistryEnvironmentVariableW;
}
while ( EnvVar ){
wsprintf(OutputBuffer,L"%s=%s",
EnvVar->Variable,
EnvVar->Value
);
AddLineToReport( SINGLE_INDENT, RFO_SINGLELINE, OutputBuffer, NULL );
EnvVar = NextEnvVarFunc();
}
return TRUE;
}
BOOL
EnvDisplayList(
IN HWND hWnd,
IN UINT iDisplayOption
)
/*++
Routine Description:
Displays the appropriate enviroment variables in the ListView box
Arguments:
hWnd - to the ListView Window
iDisplayOption - indicated whether we are displaying user or system variables
Return Value:
BOOL - TRUE if successful
--*/
{
LV_COLUMN lvc;
UINT index = 0;
TCHAR szBuffer[128];
RECT rect;
BOOL Success;
KEY SystemEnvironKey;
KEY UserEnvironKey;
static
UINT iType;
//
// Restore the initial state of the KEYs.
//
CopyMemory(
&SystemEnvironKey,
&_SystemEnvironKey,
sizeof( SystemEnvironKey )
);
CopyMemory(
&UserEnvironKey,
&_UserEnvironKey,
sizeof( UserEnvironKey )
);
// as long as this is not 0 set iType to iDisplayOption
if (iDisplayOption)
iType = iDisplayOption;
// make sure we have a valid type
if ( (iType != IDC_PUSH_SHOW_SYSTEM) &&
(iType != IDC_PUSH_SHOW_USER) ) {
iType = IDC_PUSH_SHOW_SYSTEM;
}
//
// initialize the list view
//
// first delete any items
Success = ListView_DeleteAllItems( hWnd );
// delete all columns
index = 2;
while(index) {
Success = ListView_DeleteColumn( hWnd, --index );
}
// Get the column rect
GetClientRect( hWnd, &rect );
//initialize the new columns
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT ;
lvc.fmt = LVCFMT_LEFT;
LoadString(_hModule, IDS_VARIABLE, szBuffer, cchSizeof(szBuffer));
lvc.pszText = szBuffer;
lvc.cx = 180;
Success = ListView_InsertColumn(hWnd, 0, &lvc);
LoadString(_hModule, IDS_VALUE, szBuffer, cchSizeof(szBuffer));
lvc.pszText = szBuffer;
lvc.cx = 400;
Success = ListView_InsertColumn( hWnd, 1, &lvc);
// do case specific column initialization
switch(iType){
case IDC_PUSH_SHOW_SYSTEM:
//
// Fill the system environment variable list box.
//
Success = FillEnvironmentListBox(
hWnd,
&SystemEnvironKey
);
DbgAssert( Success );
if( Success == FALSE ) {
return TRUE;
}
break;
case IDC_PUSH_SHOW_USER:
//
// Fill the per user environment variable list box.
//
Success = FillEnvironmentListBox(
hWnd,
&UserEnvironKey
);
DbgAssert( Success );
if( Success == FALSE ) {
return TRUE;
}
break;
}
//
// Set the column widths
//
ListView_SetColumnWidth( hWnd, 0, LVSCW_AUTOSIZE);
if ( ListView_GetColumnWidth( hWnd, 0) < 60 )
{
ListView_SetColumnWidth( hWnd, 0, 60);
}
ListView_SetColumnWidth( hWnd, 1, LVSCW_AUTOSIZE);
UpdateWindow ( hWnd );
}
BOOL
InitializeEnvironmentTab(
HWND hWnd
)
/*++
Routine Description:
Adds the appropriate controls to the version tab control and
initializes any needed structures.
Arguments:
hWnd - to the main window
Return Value:
BOOL - TRUE if successful
--*/
{
HCURSOR hSaveCursor;
DLGHDR *pHdr = (DLGHDR *) GetWindowLong(
GetParent(hWnd), GWL_USERDATA);
//
// Set the pointer to an hourglass
//
hSaveCursor = SetCursor ( LoadCursor ( NULL, IDC_WAIT ) ) ;
DbgHandleAssert( hSaveCursor ) ;
//
// set state of global buttons
//
EnableControl( GetParent(hWnd),
IDC_PUSH_PROPERTIES,
FALSE);
EnableControl( GetParent(hWnd),
IDC_PUSH_REFRESH,
FALSE);
//
// Size and position the child dialog
//
SetWindowPos(hWnd, HWND_TOP,
pHdr->rcDisplay.left,
pHdr->rcDisplay.top,
pHdr->rcDisplay.right - pHdr->rcDisplay.left,
pHdr->rcDisplay.bottom - pHdr->rcDisplay.top,
SWP_SHOWWINDOW);
//
// Set the extended style to get full row selection
//
SendDlgItemMessage(hWnd, IDC_LV_ENV, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
//
// Initialize the selection buttons
//
SendDlgItemMessage( hWnd,
IDC_PUSH_SHOW_SYSTEM,
BM_SETCHECK,
BST_CHECKED,
0
);
//
// Disable the User button if we are remote
//
if(_fIsRemote){
EnableControl( hWnd, IDC_PUSH_SHOW_USER, FALSE);
} else {
EnableControl( hWnd, IDC_PUSH_SHOW_USER, TRUE);
}
UpdateWindow( hWnd );
//
// Fill out the fields initially with services
//
{
EnvDisplayList( GetDlgItem( hWnd, IDC_LV_ENV ), IDC_PUSH_SHOW_SYSTEM);
}
SetCursor ( hSaveCursor ) ;
return( TRUE );
}
DWORD
WinMSDExpandEnvironmentStrings(
LPCWSTR lpSrc,
LPWSTR lpDst,
DWORD nSize
)
{
DWORD Length;
DWORD indexSrc = 0;
DWORD indexDst = 0;
TCHAR szTemp[64];
TCHAR szSystemRoot[64];
DWORD cbSystemRoot;
UINT Success;
HKEY hkey;
ZeroMemory(szSystemRoot, sizeof(szSystemRoot));
if (_fIsRemote)
{
//
// first get the remote systems %systemroot% value
//
if (!RegOpenKeyEx(_hKeyLocalMachine, SZ_SYSTEMROOTKEY, 0, KEY_READ, &hkey))
{
cbSystemRoot = sizeof(szSystemRoot);
if (RegQueryValueEx(hkey, L"SystemRoot", NULL, NULL, (LPBYTE) szSystemRoot, &cbSystemRoot) == ERROR_SUCCESS)
{
//
// if we are remote, the only env var we are
// going to expand is %systemroot%, the value of
// which we read from the remote registry
//
while( lpSrc[indexSrc] != L'\0')
{
lstrcpyn(szTemp, &lpSrc[indexSrc], 13 );
if(lstrcmpi(L"%systemroot%", szTemp ) == 0)
{
lstrcpy(&lpDst[indexDst], szSystemRoot);
indexDst += lstrlen(szSystemRoot);
indexSrc += 12;
}
else
{
lpDst[indexDst++] = lpSrc[indexSrc++];
}
}
lpDst[indexDst++] = L'\0';
}
else
{
//
// we failed to get a windir var from the remote system, so return raw string
//
lstrcpyn(lpDst, lpSrc, nSize);
RegCloseKey(hkey);
return nSize;
}
RegCloseKey(hkey);
}
Length = indexDst;
}
else //we are local, so call the real version of the API
{
Length = ExpandEnvironmentStrings( lpSrc, lpDst, nSize );
}
return Length;
}