|
|
//*************************************************************
// File name: envvar.c
//
// Description: Contains the environment variable functions
//
//
// Microsoft Confidential
// Copyright (c) Microsoft Corporation 1996
// All rights reserved
//
//*************************************************************
#include "uenv.h"
#include "strsafe.h"
//
// Max environment variable length
//
#define MAX_VALUE_LEN 1024
//
// Environment variables
//
#define COMPUTERNAME_VARIABLE TEXT("COMPUTERNAME")
#define HOMEDRIVE_VARIABLE TEXT("HOMEDRIVE")
#define HOMESHARE_VARIABLE TEXT("HOMESHARE")
#define HOMEPATH_VARIABLE TEXT("HOMEPATH")
#define SYSTEMDRIVE_VARIABLE TEXT("SystemDrive")
#define SYSTEMROOT_VARIABLE TEXT("SystemRoot")
#define USERNAME_VARIABLE TEXT("USERNAME")
#define USERDOMAIN_VARIABLE TEXT("USERDOMAIN")
#define USERDNSDOMAIN_VARIABLE TEXT("USERDNSDOMAIN")
#define USERPROFILE_VARIABLE TEXT("USERPROFILE")
#define ALLUSERSPROFILE_VARIABLE TEXT("ALLUSERSPROFILE")
#define PATH_VARIABLE TEXT("Path")
#define LIBPATH_VARIABLE TEXT("LibPath")
#define OS2LIBPATH_VARIABLE TEXT("Os2LibPath")
#define PROGRAMFILES_VARIABLE TEXT("ProgramFiles")
#define COMMONPROGRAMFILES_VARIABLE TEXT("CommonProgramFiles")
#if defined(WX86) || defined(_WIN64)
#define PROGRAMFILESX86_VARIABLE TEXT("ProgramFiles(x86)")
#define COMMONPROGRAMFILESX86_VARIABLE TEXT("CommonProgramFiles(x86)")
#endif
#define USER_ENV_SUBKEY TEXT("Environment")
#define USER_VOLATILE_ENV_SUBKEY TEXT("Volatile Environment")
//
// Parsing information for autoexec.bat
//
#define AUTOEXECPATH_VARIABLE TEXT("AutoexecPath")
#define PARSE_AUTOEXEC_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon")
#define PARSE_AUTOEXEC_ENTRY TEXT("ParseAutoexec")
#define PARSE_AUTOEXEC_DEFAULT TEXT("1")
#define MAX_PARSE_AUTOEXEC_BUFFER 2
#define SYS_ENVVARS TEXT("System\\CurrentControlSet\\Control\\Session Manager\\Environment")
BOOL UpdateSystemEnvironment(PVOID *pEnv); BOOL GetUserNameAndDomain(HANDLE hToken, LPTSTR *UserName, LPTSTR *UserDomain); BOOL GetUserNameAndDomainSlowly(HANDLE hToken, LPTSTR *UserName, LPTSTR *UserDomain); LPTSTR GetUserDNSDomainName(LPTSTR lpDomain, HANDLE hUserToken); LONG GetHKeyCU(HANDLE hToken, HKEY *hKeyCU); BOOL ProcessAutoexec(PVOID *pEnv); BOOL AppendNTPathWithAutoexecPath(PVOID *pEnv, LPTSTR lpPathVariable, LPTSTR lpAutoexecPath); BOOL SetEnvironmentVariables(PVOID *pEnv, LPTSTR lpRegSubKey, HKEY hKeyCU); #ifdef _X86_
BOOL IsPathIncludeRemovable(LPTSTR lpValue); #endif
__inline BOOL SafeGetEnvironmentVariable(LPCTSTR lpName, LPTSTR lpBuffer, DWORD nSize) { DWORD dwRet = GetEnvironmentVariable(lpName, lpBuffer, nSize); return (dwRet > 0) && (dwRet < nSize); }
//*************************************************************
//
// CreateEnvironmentBlock()
//
// Purpose: Creates the environment variables for the
// specificed hToken. If hToken is NULL, the
// environment block will only contain system
// variables.
//
// Parameters: pEnv - Receives the environment block
// hToken - User's token or NULL
// bInherit - Inherit the current process environment
//
// Return: TRUE if successful
// FALSE if not
//
// Comments: The pEnv value must be destroyed by
// calling DestroyEnvironmentBlock
//
// History: Date Author Comment
// 6/19/96 ericflo Created
//
//*************************************************************
BOOL WINAPI CreateEnvironmentBlock (LPVOID *pEnv, HANDLE hToken, BOOL bInherit) { LPTSTR szBuffer = NULL; LPTSTR szValue = NULL; LPTSTR szExpValue = NULL; DWORD dwBufferSize = MAX_PATH+1; NTSTATUS Status; LPTSTR UserName = NULL; LPTSTR UserDomain = NULL; LPTSTR UserDNSDomain = NULL; HKEY hKey, hKeyCU; DWORD dwDisp, dwType, dwSize; TCHAR szParseAutoexec[MAX_PARSE_AUTOEXEC_BUFFER]; LONG dwError; BOOL bRetVal = FALSE;
//
// Arg check
//
if (!pEnv) { SetLastError (ERROR_INVALID_PARAMETER); goto Exit; }
Status = RtlCreateEnvironment((BOOLEAN)bInherit, pEnv); if (!NT_SUCCESS(Status)) { goto Exit; }
//
// Allocate memory for Local variables to avoid stack overflow
//
szBuffer = (LPTSTR)LocalAlloc(LPTR, (MAX_PATH+1)*sizeof(TCHAR)); if (!szBuffer) { DebugMsg((DM_WARNING, TEXT("CreateEnvironmentBlock: Out of memory"))); goto Exit; }
szValue = (LPTSTR)LocalAlloc(LPTR, (MAX_VALUE_LEN+1)*sizeof(TCHAR)); if (!szValue) { DebugMsg((DM_WARNING, TEXT("CreateEnvironmentBlock: Out of memory"))); goto Exit; }
szExpValue = (LPTSTR)LocalAlloc(LPTR, (MAX_VALUE_LEN+1)*sizeof(TCHAR)); if (!szExpValue) { DebugMsg((DM_WARNING, TEXT("CreateEnvironmentBlock: Out of memory"))); goto Exit; }
//
// First start by getting the systemroot and systemdrive values and
// setting it in the new environment.
//
if ( SafeGetEnvironmentVariable(SYSTEMROOT_VARIABLE, szBuffer, dwBufferSize) ) { SetEnvironmentVariableInBlock(pEnv, SYSTEMROOT_VARIABLE, szBuffer, TRUE); }
if ( SafeGetEnvironmentVariable(SYSTEMDRIVE_VARIABLE, szBuffer, dwBufferSize) ) { SetEnvironmentVariableInBlock(pEnv, SYSTEMDRIVE_VARIABLE, szBuffer, TRUE); }
//
// Set the all users profile location.
//
dwBufferSize = MAX_PATH+1; if (GetAllUsersProfileDirectory(szBuffer, &dwBufferSize)) { SetEnvironmentVariableInBlock(pEnv, ALLUSERSPROFILE_VARIABLE, szBuffer, TRUE); }
//
// We must examine the registry directly to pull out
// the system environment variables, because they
// may have changed since the system was booted.
//
if (!UpdateSystemEnvironment(pEnv)) { RtlDestroyEnvironment(*pEnv); goto Exit; }
//
// Set the computername
//
dwBufferSize = MAX_PATH+1; if (GetComputerName (szBuffer, &dwBufferSize)) { SetEnvironmentVariableInBlock(pEnv, COMPUTERNAME_VARIABLE, szBuffer, TRUE); }
//
// Set the default user profile location
//
dwBufferSize = MAX_PATH+1; if (GetDefaultUserProfileDirectory(szBuffer, &dwBufferSize)) { SetEnvironmentVariableInBlock(pEnv, USERPROFILE_VARIABLE, szBuffer, TRUE); }
//
// Set the Program Files environment variable
//
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion"), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
dwSize = (MAX_VALUE_LEN+1)*sizeof(TCHAR); if (RegQueryValueEx (hKey, TEXT("ProgramFilesDir"), NULL, &dwType, (LPBYTE) szValue, &dwSize) == ERROR_SUCCESS) {
if (SUCCEEDED(SafeExpandEnvironmentStrings (szValue, szExpValue, (MAX_VALUE_LEN+1)))) SetEnvironmentVariableInBlock(pEnv, PROGRAMFILES_VARIABLE, szExpValue, TRUE); }
dwSize = (MAX_VALUE_LEN+1)*sizeof(TCHAR); if (RegQueryValueEx (hKey, TEXT("CommonFilesDir"), NULL, &dwType, (LPBYTE) szValue, &dwSize) == ERROR_SUCCESS) {
if (SUCCEEDED(SafeExpandEnvironmentStrings (szValue, szExpValue, (MAX_VALUE_LEN+1)))) SetEnvironmentVariableInBlock(pEnv, COMMONPROGRAMFILES_VARIABLE, szExpValue, TRUE); }
#if defined(WX86) || defined(_WIN64)
dwSize = (MAX_VALUE_LEN+1)*sizeof(TCHAR); if (RegQueryValueEx (hKey, TEXT("ProgramFilesDir (x86)"), NULL, &dwType, (LPBYTE) szValue, &dwSize) == ERROR_SUCCESS) {
if (SUCCEEDED(SafeExpandEnvironmentStrings (szValue, szExpValue, (MAX_VALUE_LEN+1)))) SetEnvironmentVariableInBlock(pEnv, PROGRAMFILESX86_VARIABLE, szExpValue, TRUE); }
dwSize = (MAX_VALUE_LEN+1)*sizeof(TCHAR); if (RegQueryValueEx (hKey, TEXT("CommonFilesDir (x86)"), NULL, &dwType, (LPBYTE) szValue, &dwSize) == ERROR_SUCCESS) {
if (SUCCEEDED(SafeExpandEnvironmentStrings (szValue, szExpValue, (MAX_VALUE_LEN+1)))) SetEnvironmentVariableInBlock(pEnv, COMMONPROGRAMFILESX86_VARIABLE, szExpValue, TRUE); } #endif
RegCloseKey (hKey); }
//
// If hToken is NULL, we can exit now since the caller only wants
// system environment variables.
//
if (!hToken) { bRetVal = TRUE; goto Exit; }
//
// Open the HKEY_CURRENT_USER for this token.
//
dwError = GetHKeyCU(hToken, &hKeyCU);
//
// if the hive is not found assume that the caller just needs the system attribute.
//
if ((!hKeyCU) && (dwError == ERROR_FILE_NOT_FOUND)) { bRetVal = TRUE; goto Exit; }
if (!hKeyCU) { RtlDestroyEnvironment(*pEnv); DebugMsg((DM_WARNING, TEXT("CreateEnvironmentBlock: Failed to open HKEY_CURRENT_USER, error = %d"), dwError)); goto Exit; }
//
// Set the user's name and domain.
//
if (!GetUserNameAndDomain(hToken, &UserName, &UserDomain)) { GetUserNameAndDomainSlowly(hToken, &UserName, &UserDomain); } UserDNSDomain = GetUserDNSDomainName(UserDomain, hToken); SetEnvironmentVariableInBlock( pEnv, USERNAME_VARIABLE, UserName, TRUE); SetEnvironmentVariableInBlock( pEnv, USERDOMAIN_VARIABLE, UserDomain, TRUE); SetEnvironmentVariableInBlock( pEnv, USERDNSDOMAIN_VARIABLE, UserDNSDomain, TRUE); LocalFree(UserName); LocalFree(UserDomain); LocalFree(UserDNSDomain);
//
// Set the user's profile location.
//
dwBufferSize = MAX_PATH+1; if (GetUserProfileDirectory(hToken, szBuffer, &dwBufferSize)) { SetEnvironmentVariableInBlock(pEnv, USERPROFILE_VARIABLE, szBuffer, TRUE); }
//
// Process autoexec.bat
//
StringCchCopy (szParseAutoexec, ARRAYSIZE(szParseAutoexec), PARSE_AUTOEXEC_DEFAULT);
if (RegCreateKeyEx (hKeyCU, PARSE_AUTOEXEC_KEY, 0, 0, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hKey, &dwDisp) == ERROR_SUCCESS) {
//
// Query the current value. If it doesn't exist, then add
// the entry for next time.
//
dwBufferSize = sizeof (TCHAR) * MAX_PARSE_AUTOEXEC_BUFFER; if (RegQueryValueEx (hKey, PARSE_AUTOEXEC_ENTRY, NULL, &dwType, (LPBYTE) szParseAutoexec, &dwBufferSize) != ERROR_SUCCESS) {
//
// Set the default value
//
RegSetValueEx (hKey, PARSE_AUTOEXEC_ENTRY, 0, REG_SZ, (LPBYTE) szParseAutoexec, sizeof (TCHAR) * lstrlen (szParseAutoexec) + 1); }
//
// Close key
//
RegCloseKey (hKey); }
//
// Process autoexec if appropriate
//
if (szParseAutoexec[0] == TEXT('1')) { ProcessAutoexec(pEnv); }
//
// Set User environment variables.
//
SetEnvironmentVariables(pEnv, USER_ENV_SUBKEY, hKeyCU);
//
// Set User volatile environment variables.
//
SetEnvironmentVariables(pEnv, USER_VOLATILE_ENV_SUBKEY, hKeyCU);
//
// Merge the paths
//
AppendNTPathWithAutoexecPath(pEnv, PATH_VARIABLE, AUTOEXECPATH_VARIABLE);
RegCloseKey (hKeyCU);
bRetVal = TRUE;
Exit:
if (szBuffer) { LocalFree(szBuffer); }
if (szValue) { LocalFree(szValue); }
if (szExpValue) { LocalFree(szExpValue); } return bRetVal; }
//*************************************************************
//
// DestroyEnvironmentBlock()
//
// Purpose: Frees the environment block created by
// CreateEnvironmentBlock
//
// Parameters: lpEnvironment - Pointer to variables
//
// Return: TRUE if successful
// FALSE if an error occurs
//
// Comments:
//
// History: Date Author Comment
// 6/19/96 ericflo Created
//
//*************************************************************
BOOL WINAPI DestroyEnvironmentBlock (LPVOID lpEnvironment) {
if (!lpEnvironment) { SetLastError (ERROR_INVALID_PARAMETER); return FALSE; }
RtlDestroyEnvironment(lpEnvironment);
return TRUE; }
//*************************************************************
//
// UpdateSystemEnvironment()
//
// Purpose: Reads the system environment variables from the
// registry.
//
// Parameters: pEnv - Environment block pointer
//
// Return: TRUE if successful
// FALSE if an error occurs
//
// Comments:
//
// History: Date Author Comment
// 6/21/96 ericflo Ported
//
//*************************************************************
BOOL UpdateSystemEnvironment(PVOID *pEnv) {
HKEY KeyHandle = NULL; DWORD Result; DWORD ValueNameLength; DWORD Type; DWORD DataLength; DWORD cValues; /* address of buffer for number of value identifiers */ DWORD chMaxValueName; /* address of buffer for longest value name length */ DWORD cbMaxValueData; /* address of buffer for longest value data length */ FILETIME FileTime; PTCHAR ValueName = NULL; PTCHAR ValueData = NULL; DWORD i; BOOL Bool; PTCHAR ExpandedValue; BOOL rc = TRUE;
Result = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, SYS_ENVVARS, 0, KEY_QUERY_VALUE, &KeyHandle );
if ( Result != ERROR_SUCCESS ) {
DebugMsg((DM_WARNING, TEXT("UpdateSystemEnvironment: RegOpenKeyEx failed, error = %d"),Result)); return( TRUE ); }
Result = RegQueryInfoKey( KeyHandle, NULL, /* address of buffer for class string */ NULL, /* address of size of class string buffer */ NULL, /* reserved */ NULL, /* address of buffer for number of subkeys */ NULL, /* address of buffer for longest subkey */ NULL, /* address of buffer for longest class string length */ &cValues, /* address of buffer for number of value identifiers */ &chMaxValueName, /* address of buffer for longest value name length */ &cbMaxValueData, /* address of buffer for longest value data length */ NULL, /* address of buffer for descriptor length */ &FileTime /* address of buffer for last write time */ );
if ( Result != NO_ERROR && Result != ERROR_MORE_DATA ) { DebugMsg((DM_WARNING, TEXT("UpdateSystemEnvironment: RegQueryInfoKey failed, error = %d"),Result)); rc = TRUE; goto Cleanup; }
//
// No need to adjust the datalength for TCHAR issues
//
ValueData = LocalAlloc(LPTR, cbMaxValueData);
if ( ValueData == NULL ) { rc = FALSE; goto Cleanup; }
//
// The maximum value name length comes back in characters, convert to bytes
// before allocating storage. Allow for trailing NULL also.
//
ValueName = LocalAlloc(LPTR, (++chMaxValueName) * sizeof( TCHAR ) );
if ( ValueName == NULL ) { rc = FALSE; goto Cleanup; }
//
// To exit from here on, set rc and jump to Cleanup
//
for (i=0; i<cValues ; i++) {
ValueNameLength = chMaxValueName; DataLength = cbMaxValueData;
Result = RegEnumValue ( KeyHandle, i, ValueName, &ValueNameLength, // Size in TCHARs
NULL, &Type, (LPBYTE)ValueData, &DataLength // Size in bytes
);
if ( Result != ERROR_SUCCESS ) {
//
// Problem getting the value. We can either try
// the rest or punt completely.
//
goto Cleanup; }
//
// If the buffer size is greater than the max allowed,
// terminate the string at MAX_VALUE_LEN - 1.
//
if (DataLength >= (MAX_VALUE_LEN * sizeof(TCHAR))) { ValueData[MAX_VALUE_LEN-1] = TEXT('\0'); }
switch ( Type ) { case REG_SZ: {
Bool = SetEnvironmentVariableInBlock( pEnv, ValueName, ValueData, TRUE );
if ( !Bool ) { DebugMsg((DM_WARNING, TEXT("UpdateSystemEnvironment: Failed to set environment variable <%s> to <%s> with %d."), ValueName, ValueData, GetLastError())); }
break; } default: { continue; } } }
//
// To exit from here on, set rc and jump to Cleanup
//
for (i=0; i<cValues ; i++) {
ValueNameLength = chMaxValueName; DataLength = cbMaxValueData;
Result = RegEnumValue ( KeyHandle, i, ValueName, &ValueNameLength, // Size in TCHARs
NULL, &Type, (LPBYTE)ValueData, &DataLength // Size in bytes
);
if ( Result != ERROR_SUCCESS ) {
//
// Problem getting the value. We can either try
// the rest or punt completely.
//
goto Cleanup; }
//
// If the buffer size is greater than the max allowed,
// terminate the string at MAX_VALUE_LEN - 1.
//
if (DataLength >= (MAX_VALUE_LEN * sizeof(TCHAR))) { ValueData[MAX_VALUE_LEN-1] = TEXT('\0'); }
switch ( Type ) { case REG_EXPAND_SZ: {
ExpandedValue = AllocAndExpandEnvironmentStrings( ValueData );
Bool = SetEnvironmentVariableInBlock( pEnv, ValueName, ExpandedValue, TRUE );
LocalFree( ExpandedValue );
if ( !Bool ) { DebugMsg((DM_WARNING, TEXT("UpdateSystemEnvironment: Failed to set environment variable <%s> to <%s> with %d."), ValueName, ValueData, GetLastError())); }
break; } default: { continue; } } }
Cleanup:
if (KeyHandle) RegCloseKey(KeyHandle);
if (ValueName) LocalFree( ValueName );
if (ValueData) LocalFree( ValueData );
return( rc ); }
//*************************************************************
//
// GetUserNameAndDomain()
//
// Purpose: Gets the user's name and domain
//
// Parameters: hToken - User's token
// UserName - Receives pointer to user's name
// UserDomain - Receives pointer to user's domain
//
// Return: TRUE if successful
// FALSE if an error occurs
//
// Comments:
//
// History: Date Author Comment
// 6/21/96 ericflo Ported
//
//*************************************************************
BOOL GetUserNameAndDomain(HANDLE hToken, LPTSTR *UserName, LPTSTR *UserDomain) { BOOL bResult = FALSE; LPTSTR lpTemp, lpDomain = NULL; LPTSTR lpUserName, lpUserDomain; HANDLE hOldToken; DWORD dwSize;
//
// Impersonate the user
//
if (!ImpersonateUser(hToken, &hOldToken)) { DebugMsg((DM_VERBOSE, TEXT("GetUserNameAndDomain Failed to impersonate user"))); goto Exit; }
//
// Get the username in NT4 format
//
lpDomain = MyGetUserNameEx (NameSamCompatible);
RevertToUser(&hOldToken);
if (!lpDomain) { DebugMsg((DM_WARNING, TEXT("GetUserNameAndDomain: MyGetUserNameEx failed for NT4 style name with %d"), GetLastError())); goto Exit; }
//
// Look for the \ between the domain and username and replace
// it with a NULL
//
lpTemp = lpDomain;
while (*lpTemp && ((*lpTemp) != TEXT('\\'))) lpTemp++;
if (*lpTemp != TEXT('\\')) { DebugMsg((DM_WARNING, TEXT("GetUserNameAndDomain Failed to find slash in NT4 style name: <%s>"), lpDomain)); goto Exit; }
*lpTemp = TEXT('\0'); lpTemp++;
//
// Allocate space for the results
//
dwSize = lstrlen(lpTemp) + 1; lpUserName = LocalAlloc (LPTR, dwSize * sizeof(TCHAR));
if (!lpUserName) { DebugMsg((DM_WARNING, TEXT("GetUserNameAndDomain Failed to allocate memory with %d"), GetLastError())); goto Exit; }
StringCchCopy (lpUserName, dwSize, lpTemp);
dwSize = lstrlen(lpDomain) + 1; lpUserDomain = LocalAlloc (LPTR, dwSize * sizeof(TCHAR));
if (!lpUserDomain) { DebugMsg((DM_WARNING, TEXT("GetUserNameAndDomain Failed to allocate memory with %d"), GetLastError())); LocalFree (lpUserName); goto Exit; }
StringCchCopy (lpUserDomain, dwSize, lpDomain);
//
// Save the results in the outbound arguments
//
*UserName = lpUserName; *UserDomain = lpUserDomain;
//
// Success
//
bResult = TRUE;
Exit:
if (lpDomain) { LocalFree (lpDomain); }
return(bResult); }
//*************************************************************
//
// GetUserNameAndDomainSlowly()
//
// Purpose: Gets the user's name and domain from a DC
//
// Parameters: hToken - User's token
// UserName - Receives pointer to user's name
// UserDomain - Receives pointer to user's domain
//
// Return: TRUE if successful
// FALSE if an error occurs
//
// Comments:
//
// History: Date Author Comment
// 6/21/96 ericflo Ported
//
//*************************************************************
BOOL GetUserNameAndDomainSlowly(HANDLE hToken, LPTSTR *UserName, LPTSTR *UserDomain) { LPTSTR lpUserName = NULL; LPTSTR lpUserDomain = NULL; DWORD cbAccountName = 0; DWORD cbUserDomain = 0; SID_NAME_USE SidNameUse; BOOL bRet = FALSE; PSID pSid;
//
// Get the user's sid
//
pSid = GetUserSid (hToken);
if (!pSid) { return FALSE; }
//
// Get the space needed for the User name and the Domain name
//
if (!LookupAccountSid(NULL, pSid, NULL, &cbAccountName, NULL, &cbUserDomain, &SidNameUse ) ) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { goto Error; } }
lpUserName = (LPTSTR)LocalAlloc(LPTR, cbAccountName*sizeof(TCHAR)); if (!lpUserName) { goto Error; }
lpUserDomain = (LPTSTR)LocalAlloc(LPTR, cbUserDomain*sizeof(WCHAR)); if (!lpUserDomain) { LocalFree(lpUserName); goto Error; }
//
// Now get the user name and domain name
//
if (!LookupAccountSid(NULL, pSid, lpUserName, &cbAccountName, lpUserDomain, &cbUserDomain, &SidNameUse ) ) {
LocalFree(lpUserName); LocalFree(lpUserDomain); goto Error; }
*UserName = lpUserName; *UserDomain = lpUserDomain; bRet = TRUE;
Error: DeleteUserSid (pSid);
return(bRet); }
//*************************************************************
//
// GetUserDNSDomainName()
//
// Purpose: Gets the DNS domain name for the user
//
// Parameters: lpDomain - User's flat domain name
// hUserToken - User's token
//
//
// Return: DNS domain name if successful
// NULL if an error occurs
//
//*************************************************************
LPTSTR GetUserDNSDomainName(LPTSTR lpDomain, HANDLE hUserToken) { LPTSTR lpDnsDomain = NULL, lpTemp = NULL; DWORD dwBufferSize; TCHAR szBuffer[MAX_PATH]; INT iRole; HANDLE hOldToken; BOOL bResult = FALSE;
//
// Check if this machine is running standalone, if so, there won't be
// a DNS domain name
//
if (!GetMachineRole (&iRole)) { DebugMsg((DM_WARNING, TEXT("GetUserDNSDomainName: Failed to get the role of the computer."))); return NULL; }
if (iRole == 0) { DebugMsg((DM_VERBOSE, TEXT("GetUserDNSDomainName: Computer is running standalone. No DNS domain name available."))); return NULL; }
//
// Get the computer name to see if the user logged on locally
//
dwBufferSize = ARRAYSIZE(szBuffer);
if (GetComputerName (szBuffer, &dwBufferSize)) { if (!lstrcmpi(lpDomain, szBuffer)) { DebugMsg((DM_VERBOSE, TEXT("GetUserDNSDomainName: Local user account. No DNS domain name available."))); return NULL; } }
if (LoadString (g_hDllInstance, IDS_NT_AUTHORITY, szBuffer, ARRAYSIZE(szBuffer))) { if (!lstrcmpi(lpDomain, szBuffer)) { DebugMsg((DM_VERBOSE, TEXT("GetUserDNSDomainName: Domain name is NT Authority. No DNS domain name available."))); return NULL; } }
if (LoadString (g_hDllInstance, IDS_BUILTIN, szBuffer, ARRAYSIZE(szBuffer))) { if (!lstrcmpi(lpDomain, szBuffer)) { DebugMsg((DM_VERBOSE, TEXT("GetUserDNSDomainName: Domain name is BuiltIn. No DNS domain name available."))); return NULL; } }
//
// Impersonate the user
//
if (!ImpersonateUser(hUserToken, &hOldToken)) { DebugMsg((DM_VERBOSE, TEXT("GetUserDNSDomainName: Failed to impersonate user"))); goto Exit; }
//
// Get the username in DnsDomainName format
//
lpDnsDomain = MyGetUserNameEx (NameDnsDomain);
RevertToUser(&hOldToken);
if (!lpDnsDomain) { DebugMsg((DM_WARNING, TEXT("GetUserDNSDomainName: MyGetUserNameEx failed for NameDnsDomain style name with %d"), GetLastError())); goto Exit; }
//
// Look for the \ between the domain and username and replace
// it with a NULL
//
lpTemp = lpDnsDomain;
while (*lpTemp && (*lpTemp != TEXT('\\'))) lpTemp++;
if (*lpTemp != TEXT('\\')) { DebugMsg((DM_WARNING, TEXT("GetUserDNSDomainName: Failed to find slash in NameDnsDomain style name: <%s>"), lpDnsDomain)); goto Exit; }
*lpTemp = TEXT('\0'); bResult = TRUE;
Exit:
if (!bResult && lpDnsDomain) { LocalFree(lpDnsDomain); lpDnsDomain = NULL; }
return lpDnsDomain; }
//*************************************************************
//
// GetHKeyCU()
//
// Purpose: Get HKEY_CURRENT_USER for the given hToken
//
// Parameters: hToken - token handle
//
// Return: hKey if successful
// NULL if an error occurs
//
// Comments:
//
// History: Date Author Comment
// 6/21/96 ericflo Created
//
//*************************************************************
LONG GetHKeyCU(HANDLE hToken, HKEY *hKeyCU) { LPTSTR lpSidString; LONG dwError;
*hKeyCU = NULL;
lpSidString = GetSidString (hToken);
if (!lpSidString) { return GetLastError(); }
dwError = RegOpenKeyEx (HKEY_USERS, lpSidString, 0, KEY_READ, hKeyCU);
if (dwError != ERROR_SUCCESS) DebugMsg((DM_VERBOSE, TEXT("GetHkeyCU: RegOpenKey failed with error %d"), dwError));
DeleteSidString(lpSidString);
return dwError; }
/***************************************************************************\
* ProcessAutoexecPath * * Creates AutoexecPath environment variable using autoexec.bat * LpValue may be freed by this routine. * * History: * 06-02-92 Johannec Created. * \***************************************************************************/ LPTSTR ProcessAutoexecPath(PVOID pEnv, LPTSTR lpValue, DWORD cb) { LPTSTR lpt; LPTSTR lpStart; LPTSTR lpPath; DWORD ccht; UNICODE_STRING Name; UNICODE_STRING Value; BOOL bPrevAutoexecPath; WCHAR ch; DWORD dwTemp, dwCount = 0;
ccht = 1024; lpt = (LPTSTR)LocalAlloc(LPTR, ccht*sizeof(WCHAR)); if (!lpt) { return(lpValue); } *lpt = 0; lpStart = lpValue;
RtlInitUnicodeString(&Name, AUTOEXECPATH_VARIABLE); Value.Buffer = (PWCHAR)LocalAlloc(LPTR, ccht*sizeof(WCHAR)); if (!Value.Buffer) { goto Fail; }
while (NULL != (lpPath = wcsstr (lpValue, TEXT("%")))) { if (!_wcsnicmp(lpPath+1, TEXT("PATH%"), 5)) { //
// check if we have an autoexecpath already set, if not just remove
// the %path%
//
Value.Length = (USHORT)ccht * sizeof(WCHAR); Value.MaximumLength = (USHORT)ccht * sizeof(WCHAR); bPrevAutoexecPath = (BOOL)!RtlQueryEnvironmentVariable_U(pEnv, &Name, &Value);
*lpPath = 0; dwTemp = dwCount + lstrlen (lpValue); if (dwTemp < ccht) { StringCchCat(lpt, ccht, lpValue); dwCount = dwTemp; } if (bPrevAutoexecPath) { dwTemp = dwCount + lstrlen (Value.Buffer); if (dwTemp < ccht) { StringCchCat(lpt, ccht, Value.Buffer); dwCount = dwTemp; } }
*lpPath++ = TEXT('%'); lpPath += 5; // go passed %path%
lpValue = lpPath; } else { lpPath = wcsstr(lpPath+1, TEXT("%")); if (!lpPath) { lpStart = NULL; goto Fail; } lpPath++; ch = *lpPath; *lpPath = 0; dwTemp = dwCount + lstrlen (lpValue); if (dwTemp < ccht) { StringCchCat(lpt, ccht, lpValue); dwCount = dwTemp; } *lpPath = ch; lpValue = lpPath; } }
if (*lpValue) { dwTemp = dwCount + lstrlen (lpValue); if (dwTemp < ccht) { StringCchCat(lpt, ccht, lpValue); dwCount = dwTemp; } }
LocalFree(Value.Buffer); LocalFree(lpStart);
return(lpt); Fail: LocalFree(lpt); return(lpStart); }
/***************************************************************************\
* ProcessCommand * * History: * 01-24-92 Johannec Created. * \***************************************************************************/ BOOL ProcessCommand(LPSTR lpStart, PVOID *pEnv) { LPTSTR lpt, lptt; LPTSTR lpVariable; LPTSTR lpValue; LPTSTR lpExpandedValue = NULL; WCHAR c; DWORD cch, cchNeeded; LPTSTR lpu; DWORD cchVariable, cchValue;
//
// convert to Unicode
//
lpu = (LPTSTR)LocalAlloc(LPTR, (cch=lstrlenA(lpStart)+1)*sizeof(WCHAR));
if (!lpu) { return FALSE; }
if (!MultiByteToWideChar(CP_OEMCP, 0, lpStart, -1, lpu, cch)) { LocalFree(lpu); return FALSE; }
//
// Find environment variable.
//
for (lpt = lpu; *lpt && *lpt == TEXT(' '); lpt++) //skip spaces
;
if (!*lpt) { LocalFree (lpu); return(FALSE); }
lptt = lpt; for (; *lpt && *lpt != TEXT(' ') && *lpt != TEXT('='); lpt++) //find end of variable name
;
c = *lpt; *lpt = 0; cchVariable = lstrlen(lptt) + 1; lpVariable = (LPTSTR)LocalAlloc(LPTR, cchVariable*sizeof(WCHAR)); if (!lpVariable) { LocalFree (lpu); return(FALSE); }
StringCchCopy(lpVariable, cchVariable, lptt); *lpt = c;
//
// Find environment variable value.
//
for (; *lpt && (*lpt == TEXT(' ') || *lpt == TEXT('=')); lpt++) ;
if (!*lpt) { // if we have a blank path statement in the autoexec file,
// then we don't want to pass "PATH" as the environment
// variable because it trashes the system's PATH. Instead
// we want to change the variable AutoexecPath. This would have
// be handled below if a value had been assigned to the
// environment variable.
if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpVariable, -1, PATH_VARIABLE, -1) == CSTR_EQUAL) { SetEnvironmentVariableInBlock(pEnv, AUTOEXECPATH_VARIABLE, TEXT(""), TRUE); } else { SetEnvironmentVariableInBlock(pEnv, lpVariable, TEXT(""), TRUE); } LocalFree (lpVariable); LocalFree (lpu); return(FALSE); }
lptt = lpt; for (; *lpt; lpt++) //find end of varaible value
;
c = *lpt; *lpt = 0; cchValue = lstrlen(lptt) + 1; lpValue = (LPTSTR)LocalAlloc(LPTR, cchValue*sizeof(WCHAR)); if (!lpValue) { LocalFree (lpu); LocalFree(lpVariable); return(FALSE); }
StringCchCopy(lpValue, cchValue, lptt); *lpt = c;
#ifdef _X86_
// NEC98
//
// If the path includes removable drive,
// it is assumed that the drive assignment has changed from DOS.
//
if (IsNEC_98 && (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpVariable, -1, PATH_VARIABLE, -1) == CSTR_EQUAL) && IsPathIncludeRemovable(lpValue)) { LocalFree (lpu); LocalFree(lpVariable); LocalFree(lpValue); return(FALSE); } #endif
cch = 1024; lpExpandedValue = (LPTSTR)LocalAlloc(LPTR, cch*sizeof(WCHAR)); if (lpExpandedValue) { if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpVariable, -1, PATH_VARIABLE, -1) == CSTR_EQUAL) { lpValue = ProcessAutoexecPath(*pEnv, lpValue, (lstrlen(lpValue)+1)*sizeof(WCHAR)); } cchNeeded = ExpandUserEnvironmentStrings(*pEnv, lpValue, lpExpandedValue, cch); if (cchNeeded > cch) { LocalFree(lpExpandedValue); cch = cchNeeded; lpExpandedValue = (LPTSTR)LocalAlloc(LPTR, cch*sizeof(WCHAR)); if (lpExpandedValue) { ExpandUserEnvironmentStrings(*pEnv, lpValue, lpExpandedValue, cch); } } }
if (!lpExpandedValue) { lpExpandedValue = lpValue; } if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpVariable, -1, PATH_VARIABLE, -1) == CSTR_EQUAL) { SetEnvironmentVariableInBlock(pEnv, AUTOEXECPATH_VARIABLE, lpExpandedValue, TRUE); } else { SetEnvironmentVariableInBlock(pEnv, lpVariable, lpExpandedValue, FALSE); }
if (lpExpandedValue != lpValue) { LocalFree(lpExpandedValue); } LocalFree(lpVariable); LocalFree(lpValue); LocalFree (lpu);
return(TRUE); }
/***************************************************************************\
* ProcessSetCommand * * History: * 01-24-92 Johannec Created. * \***************************************************************************/ BOOL ProcessSetCommand(LPSTR lpStart, PVOID *pEnv) { LPSTR lpt;
//
// Find environment variable.
//
for (lpt = lpStart; *lpt && *lpt != TEXT(' '); lpt++) ;
if (!*lpt) return(FALSE);
return (ProcessCommand(lpt, pEnv));
}
/***************************************************************************\
* ProcessAutoexec * * History: * 01-24-92 Johannec Created. * \***************************************************************************/ BOOL ProcessAutoexec( PVOID *pEnv ) { HANDLE fh = NULL; DWORD dwFileSize; DWORD dwBytesRead; CHAR *lpBuffer = NULL; CHAR *token; CHAR Seps[] = "&\n\r"; // Seperators for tokenizing autoexec.bat
BOOL Status = FALSE; TCHAR szAutoExecBat [] = TEXT("c:\\autoexec.bat"); #ifdef _X86_
TCHAR szTemp[3]; #endif
UINT uiErrMode;
// There is a case where the OS might not be booting from drive
// C, so we can not assume that the autoexec.bat file is on c:\.
// Set the error mode so the user doesn't see the critical error
// popup and attempt to open the file on c:\.
uiErrMode = SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
#ifdef _X86_
if (IsNEC_98) { if (GetEnvironmentVariable (TEXT("SystemDrive"), szTemp, 3)) { szAutoExecBat[0] = szTemp[0]; } } #endif
// if autoexec.bat is encrypted then ignore it as it creates cyclic-dependency
// and don't allow any user to logon
if (GetFileAttributes(szAutoExecBat) & FILE_ATTRIBUTE_ENCRYPTED) { SetErrorMode(uiErrMode); goto Exit; }
fh = CreateFile (szAutoExecBat, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
SetErrorMode (uiErrMode);
if (fh == INVALID_HANDLE_VALUE) { goto Exit; //could not open autoexec.bat file, we're done.
} dwFileSize = GetFileSize(fh, NULL); if (dwFileSize == -1) { goto Exit; // can't read the file size
}
lpBuffer = (PCHAR)LocalAlloc(LPTR, dwFileSize+1); if (!lpBuffer) { goto Exit; }
Status = ReadFile(fh, lpBuffer, dwFileSize, &dwBytesRead, NULL); if (!Status) { goto Exit; // error reading file
}
//
// Zero terminate the buffer so we don't walk off the end
//
DmAssert(dwBytesRead <= dwFileSize); lpBuffer[dwBytesRead] = 0;
//
// Search for SET and PATH commands
//
token = strtok(lpBuffer, Seps); while (token != NULL) { for (;*token && *token == ' ';token++) //skip spaces
; if (*token == TEXT('@')) token++; for (;*token && *token == ' ';token++) //skip spaces
; if (!_strnicmp(token, "Path", 4)) { ProcessCommand(token, pEnv); } if (!_strnicmp(token, "SET", 3)) { ProcessSetCommand(token, pEnv); } token = strtok(NULL, Seps); } Exit: if (fh) { CloseHandle(fh); } if (lpBuffer) { LocalFree(lpBuffer); } if (!Status) { DebugMsg((DM_WARNING, TEXT("ProcessAutoexec: Cannot process autoexec.bat."))); } return(Status); }
/***************************************************************************\
* BuildEnvironmentPath * * * History: * 2-28-92 Johannec Created * \***************************************************************************/ BOOL BuildEnvironmentPath(PVOID *pEnv, LPTSTR lpPathVariable, LPTSTR lpPathValue) { NTSTATUS Status; UNICODE_STRING Name; UNICODE_STRING Value; WCHAR lpTemp[1025]; DWORD cch;
if (!*pEnv) { return(FALSE); } RtlInitUnicodeString(&Name, lpPathVariable); cch = 1024; Value.Buffer = (PWCHAR)LocalAlloc(LPTR, cch*sizeof(WCHAR)); if (!Value.Buffer) { return(FALSE); } Value.Length = (USHORT)(sizeof(WCHAR) * cch); Value.MaximumLength = (USHORT)(sizeof(WCHAR) * cch); Status = RtlQueryEnvironmentVariable_U(*pEnv, &Name, &Value); if (!NT_SUCCESS(Status)) { LocalFree(Value.Buffer); Value.Length = 0; *lpTemp = 0; } if (Value.Length) { StringCchCopy(lpTemp, ARRAYSIZE(lpTemp), Value.Buffer); if ( *( lpTemp + lstrlen(lpTemp) - 1) != TEXT(';') ) { StringCchCat(lpTemp, ARRAYSIZE(lpTemp), TEXT(";")); } LocalFree(Value.Buffer); } if (lpPathValue && ((lstrlen(lpTemp) + lstrlen(lpPathValue) + 1) < (INT)cch)) { StringCchCat(lpTemp, ARRAYSIZE(lpTemp), lpPathValue);
RtlInitUnicodeString(&Value, lpTemp);
Status = RtlSetEnvironmentVariable(pEnv, &Name, &Value); } if (NT_SUCCESS(Status)) { return(TRUE); } return(FALSE); }
/***************************************************************************\
* AppendNTPathWithAutoexecPath * * Gets the AutoexecPath created in ProcessAutoexec, and appends it to * the NT path. * * History: * 05-28-92 Johannec Created. * \***************************************************************************/ BOOL AppendNTPathWithAutoexecPath( PVOID *pEnv, LPTSTR lpPathVariable, LPTSTR lpAutoexecPath ) { NTSTATUS Status; UNICODE_STRING Name; UNICODE_STRING Value; WCHAR AutoexecPathValue[1024]; DWORD cch; BOOL Success;
if (!*pEnv) { return(FALSE); }
RtlInitUnicodeString(&Name, lpAutoexecPath); cch = 1024; Value.Buffer = (PWCHAR)LocalAlloc(LPTR, cch*sizeof(WCHAR)); if (!Value.Buffer) { return(FALSE); }
Value.Length = (USHORT)cch*sizeof(WCHAR); Value.MaximumLength = (USHORT)cch*sizeof(WCHAR); Status = RtlQueryEnvironmentVariable_U(*pEnv, &Name, &Value); if (!NT_SUCCESS(Status)) { LocalFree(Value.Buffer); return(FALSE); }
if (Value.Length) { StringCchCopy(AutoexecPathValue, ARRAYSIZE(AutoexecPathValue), Value.Buffer); }
LocalFree(Value.Buffer);
Success = BuildEnvironmentPath(pEnv, lpPathVariable, AutoexecPathValue); RtlSetEnvironmentVariable( pEnv, &Name, NULL);
return(Success); }
/***************************************************************************\
* SetEnvironmentVariables * * Reads the user-defined environment variables from the user registry * and adds them to the environment block at pEnv. * * History: * 2-28-92 Johannec Created * \***************************************************************************/ BOOL SetEnvironmentVariables( PVOID *pEnv, LPTSTR lpRegSubKey, HKEY hKeyCU ) { WCHAR lpValueName[MAX_PATH]; LPBYTE lpDataBuffer; DWORD cchDataBuffer; LPBYTE lpData; LPTSTR lpExpandedValue = NULL; DWORD cchValueName = MAX_PATH; DWORD cbData; DWORD dwType; DWORD dwIndex = 0; HKEY hkey; BOOL bResult;
if (RegOpenKeyExW(hKeyCU, lpRegSubKey, 0, KEY_READ, &hkey)) { return(FALSE); }
cchDataBuffer = 4096; lpDataBuffer = (LPBYTE)LocalAlloc(LPTR, cchDataBuffer*sizeof(WCHAR)); if (lpDataBuffer == NULL) { RegCloseKey(hkey); return(FALSE); } lpData = lpDataBuffer; cbData = cchDataBuffer * sizeof(WCHAR); bResult = TRUE; while (!RegEnumValue(hkey, dwIndex, lpValueName, &cchValueName, 0, &dwType, lpData, &cbData)) { if (cchValueName) {
//
// Limit environment variable length
//
lpData[MAX_VALUE_LEN-1] = TEXT('\0');
if (dwType == REG_SZ) { //
// The path variables PATH, LIBPATH and OS2LIBPATH must have
// their values apppended to the system path.
//
if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpValueName, -1, PATH_VARIABLE, -1) == CSTR_EQUAL || CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpValueName, -1, LIBPATH_VARIABLE, -1) == CSTR_EQUAL || CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpValueName, -1, OS2LIBPATH_VARIABLE, -1) == CSTR_EQUAL ) {
BuildEnvironmentPath(pEnv, lpValueName, (LPTSTR)lpData); } else {
//
// the other environment variables are just set.
//
SetEnvironmentVariableInBlock(pEnv, lpValueName, (LPTSTR)lpData, TRUE); } } } dwIndex++; cbData = cchDataBuffer * sizeof(WCHAR); cchValueName = MAX_PATH; }
dwIndex = 0; cbData = cchDataBuffer * sizeof(WCHAR); cchValueName = MAX_PATH;
while (!RegEnumValue(hkey, dwIndex, lpValueName, &cchValueName, 0, &dwType, lpData, &cbData)) { if (cchValueName) {
//
// Limit environment variable length
//
lpData[MAX_VALUE_LEN-1] = TEXT('\0');
if (dwType == REG_EXPAND_SZ) { DWORD cch, cchNeeded;
cch = 1024; lpExpandedValue = (LPTSTR)LocalAlloc(LPTR, cch*sizeof(WCHAR)); if (lpExpandedValue) { cchNeeded = ExpandUserEnvironmentStrings(*pEnv, (LPTSTR)lpData, lpExpandedValue, cch); if (cchNeeded > cch) { LocalFree(lpExpandedValue); cch = cchNeeded; lpExpandedValue = (LPTSTR)LocalAlloc(LPTR, cch*sizeof(WCHAR)); if (lpExpandedValue) { ExpandUserEnvironmentStrings(*pEnv, (LPTSTR)lpData, lpExpandedValue, cch); } } }
if (lpExpandedValue == NULL) { bResult = FALSE; break; }
//
// The path variables PATH, LIBPATH and OS2LIBPATH must have
// their values apppended to the system path.
//
if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpValueName, -1, PATH_VARIABLE, -1) == CSTR_EQUAL || CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpValueName, -1, LIBPATH_VARIABLE, -1) == CSTR_EQUAL || CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpValueName, -1, OS2LIBPATH_VARIABLE, -1) == CSTR_EQUAL ) {
BuildEnvironmentPath(pEnv, lpValueName, (LPTSTR)lpExpandedValue); } else {
//
// the other environment variables are just set.
//
SetEnvironmentVariableInBlock(pEnv, lpValueName, (LPTSTR)lpExpandedValue, TRUE); }
LocalFree(lpExpandedValue);
}
} dwIndex++; cbData = cchDataBuffer * sizeof(WCHAR); cchValueName = MAX_PATH; }
LocalFree(lpDataBuffer); RegCloseKey(hkey);
return(bResult); }
//*************************************************************
//
// ExpandEnvironmentStringsForUser()
//
// Purpose: Expands the source string using the environment block for the
// specified user. If hToken is null, the system environment block
// will be used (no user environment variables).
//
// Parameters: hToken - User's token (or null for system env vars)
// lpSrc - String to be expanded
// lpDest - Buffer to receive string
// dwSize - Size of dest buffer
//
// Return: TRUE if successful
// FALSE if an error occurs
//
//*************************************************************
BOOL WINAPI ExpandEnvironmentStringsForUser(HANDLE hToken, LPCTSTR lpSrc, LPTSTR lpDest, DWORD dwSize) { LPVOID pEnv; DWORD dwNeeded; BOOL bResult = FALSE;
//
// Arg check
//
if ( !lpDest || !lpSrc ) { SetLastError (ERROR_INVALID_PARAMETER); return FALSE; }
//
// Get the user's environment block
//
if (!CreateEnvironmentBlock (&pEnv, hToken, FALSE)) { DebugMsg((DM_WARNING, TEXT("ExpandEnvironmentStringsForUser: CreateEnvironmentBlock failed with = %d"), GetLastError())); return FALSE; }
//
// Expand the string
//
dwNeeded = ExpandUserEnvironmentStrings(pEnv, lpSrc, lpDest, dwSize);
if (dwNeeded && (dwNeeded < dwSize)) { bResult = TRUE; } else { SetLastError(ERROR_INSUFFICIENT_BUFFER ); }
//
// Free the environment block
//
DestroyEnvironmentBlock (pEnv);
return bResult; }
//*************************************************************
//
// GetSystemTempDirectory()
//
// Purpose: Gets the system temp directory in short form
//
// Parameters: lpDir - Receives the directory
// lpcchSize - Size of the lpDir buffer
//
//
// Return: TRUE if successful
// FALSE if an error occurs
//
//*************************************************************
BOOL WINAPI GetSystemTempDirectory(LPTSTR lpDir, LPDWORD lpcchSize) { TCHAR szTemp[MAX_PATH]; TCHAR szDirectory[MAX_PATH]; DWORD dwLength; HKEY hKey; LONG lResult; DWORD dwSize, dwType; BOOL bRetVal = FALSE; WIN32_FILE_ATTRIBUTE_DATA fad; HRESULT hr;
szTemp[0] = TEXT('\0'); szDirectory[0] = TEXT('\0');
//
// Look in the system environment variables
//
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, SYS_ENVVARS, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
//
// Check for TEMP
//
dwSize = sizeof(szTemp);
if (RegQueryValueEx (hKey, TEXT("TEMP"), NULL, &dwType, (LPBYTE) szTemp, &dwSize) == ERROR_SUCCESS) { RegCloseKey (hKey); goto FoundTemp; }
//
// Check for TMP
//
dwSize = sizeof(szTemp);
if (RegQueryValueEx (hKey, TEXT("TMP"), NULL, &dwType, (LPBYTE) szTemp, &dwSize) == ERROR_SUCCESS) { RegCloseKey (hKey); goto FoundTemp; }
RegCloseKey (hKey); }
//
// Check if %SystemRoot%\Temp exists
//
StringCchCopy (szDirectory, ARRAYSIZE(szDirectory), TEXT("%SystemRoot%\\Temp")); if (FAILED(hr = SafeExpandEnvironmentStrings (szDirectory, szTemp, ARRAYSIZE (szTemp)))) { SetLastError(HRESULT_CODE(hr)); goto Exit; }
if (GetFileAttributesEx (szTemp, GetFileExInfoStandard, &fad) && fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
goto FoundTemp; }
//
// Check if %SystemDrive%\Temp exists
//
StringCchCopy (szDirectory, ARRAYSIZE(szDirectory), TEXT("%SystemDrive%\\Temp")); if (FAILED(hr = SafeExpandEnvironmentStrings (szDirectory, szTemp, ARRAYSIZE (szTemp)))) { SetLastError(HRESULT_CODE(hr)); goto Exit; }
if (GetFileAttributesEx (szTemp, GetFileExInfoStandard, &fad) && fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
goto FoundTemp; }
//
// Last resort is %SystemRoot%
//
StringCchCopy (szTemp, ARRAYSIZE (szTemp), TEXT("%SystemRoot%"));
FoundTemp:
if (FAILED(hr = SafeExpandEnvironmentStrings (szTemp, szDirectory, ARRAYSIZE (szDirectory)))) { SetLastError(HRESULT_CODE(hr)); goto Exit; } dwLength = GetShortPathName (szDirectory, szTemp, ARRAYSIZE(szTemp)); if (dwLength > ARRAYSIZE(szTemp) || dwLength == 0) { goto Exit; }
dwLength = lstrlen(szTemp) + 1;
if (lpDir) {
if (*lpcchSize >= dwLength) { StringCchCopy (lpDir, *lpcchSize, szTemp); bRetVal = TRUE;
} else { SetLastError(ERROR_INSUFFICIENT_BUFFER); } } else { SetLastError(ERROR_INSUFFICIENT_BUFFER); }
*lpcchSize = dwLength;
Exit: return bRetVal; }
#ifdef _X86_
BOOL IsPathIncludeRemovable(LPTSTR lpValue) { LPTSTR lpt, tmp; BOOL ret = FALSE; WCHAR c; DWORD cchTmp;
cchTmp = lstrlen(lpValue) + 1; tmp = LocalAlloc(LPTR, cchTmp * sizeof(WCHAR)); if (!tmp) { DebugMsg((DM_WARNING, TEXT("IsPathIncludeRemovable : Failed to LocalAlloc (%d)"), GetLastError())); } else { StringCchCopy(tmp, cchTmp, lpValue);
lpt = tmp; while (*lpt) { // skip spaces
for ( ; *lpt && *lpt == TEXT(' '); lpt++) ;
// check if the drive is removable
if (lpt[0] && lpt[1] && lpt[1] == TEXT(':') && lpt[2]) { // ex) "A:\"
c = lpt[3]; lpt[3] = 0; if (GetDriveType(lpt) == DRIVE_REMOVABLE) { lpt[3] = c; ret = TRUE; break; } lpt[3] = c; }
// skip to the next path
for ( ; *lpt && *lpt != TEXT(';'); lpt++) ; if (*lpt) lpt++; } LocalFree(tmp); } return(ret); } #endif
|