diff options
Diffstat (limited to 'private/windows/gina/userenv/util.c')
-rw-r--r-- | private/windows/gina/userenv/util.c | 1645 |
1 files changed, 1645 insertions, 0 deletions
diff --git a/private/windows/gina/userenv/util.c b/private/windows/gina/userenv/util.c new file mode 100644 index 000000000..fa9cc8d6f --- /dev/null +++ b/private/windows/gina/userenv/util.c @@ -0,0 +1,1645 @@ +//************************************************************* +// +// Utility functions +// +// Microsoft Confidential +// Copyright (c) Microsoft Corporation 1995 +// All rights reserved +// +//************************************************************* + +#include "uenv.h" + +#define TYPICAL_STRING_LENGTH 60 + +//************************************************************* +// +// ProduceWFromA() +// +// Purpose: Creates a buffer for a Unicode string and copies +// the ANSI text into it (converting in the process) +// +// Parameters: pszA - ANSI string +// +// +// Return: Unicode pointer if successful +// NULL if an error occurs +// +// Comments: The caller needs to free this pointer. +// +// +// History: Date Author Comment +// 5/24/95 ericflo Ported +// +//************************************************************* + +LPWSTR ProduceWFromA(LPCSTR pszA) +{ + LPWSTR pszW; + int cch; + + if (!pszA) + return (LPWSTR)pszA; + + cch = MultiByteToWideChar(CP_ACP, 0, pszA, -1, NULL, 0); + + if (cch == 0) + cch = 1; + + pszW = LocalAlloc(LPTR, cch * sizeof(WCHAR)); + + if (pszW) { + if (!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszA, -1, pszW, cch)) { + LocalFree(pszW); + pszW = NULL; + } + } + + return pszW; +} + +//************************************************************* +// +// ProduceAFromW() +// +// Purpose: Creates a buffer for an ANSI string and copies +// the Unicode text into it (converting in the process) +// +// Parameters: pszW - Unicode string +// +// +// Return: ANSI pointer if successful +// NULL if an error occurs +// +// Comments: The caller needs to free this pointer. +// +// +// History: Date Author Comment +// 5/24/95 ericflo Ported +// +//************************************************************* + +LPSTR ProduceAFromW(LPCWSTR pszW) +{ + LPSTR pszA; + int cch; + + if (!pszW) + return (LPSTR)pszW; + + cch = WideCharToMultiByte(CP_ACP, 0, pszW, -1, NULL, 0, NULL, NULL); + + if (cch == 0) + cch = 1; + + pszA = LocalAlloc(LPTR, cch * sizeof(char)); + + if (pszA) { + if (!WideCharToMultiByte(CP_ACP, 0, pszW, -1, pszA, cch, NULL, NULL)) { + LocalFree(pszA); + pszA = NULL; + } + } + + return pszA; +} + + +//************************************************************* +// +// CheckSlash() +// +// Purpose: Checks for an ending slash and adds one if +// it is missing. +// +// Parameters: lpDir - directory +// +// Return: Pointer to the end of the string +// +// Comments: +// +// History: Date Author Comment +// 6/19/95 ericflo Created +// +//************************************************************* +LPTSTR CheckSlash (LPTSTR lpDir) +{ + DWORD dwStrLen; + LPTSTR lpEnd; + + lpEnd = lpDir + lstrlen(lpDir); + + if (*(lpEnd - 1) != TEXT('\\')) { + *lpEnd = TEXT('\\'); + lpEnd++; + *lpEnd = TEXT('\0'); + } + + return lpEnd; +} + + +//************************************************************* +// +// Delnode_Recurse() +// +// Purpose: Recursive delete function for Delnode +// +// Parameters: lpDir - Directory +// +// Return: TRUE if successful +// FALSE if an error occurs +// +// Comments: +// +// History: Date Author Comment +// 8/10/95 ericflo Created +// +//************************************************************* + +BOOL Delnode_Recurse (LPTSTR lpDir) +{ + WIN32_FIND_DATA fd; + HANDLE hFile; + + // + // Verbose output + // + + DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Entering, lpDir = <%s>"), lpDir)); + + + // + // Setup the current working dir + // + + if (!SetCurrentDirectory (lpDir)) { + DebugMsg((DM_WARNING, TEXT("Delnode_Recurse: Failed to set current working directory. Error = %d"), GetLastError())); + return FALSE; + } + + + // + // Find the first file + // + + hFile = FindFirstFile(c_szStarDotStar, &fd); + + if (hFile == INVALID_HANDLE_VALUE) { + + if (GetLastError() == ERROR_FILE_NOT_FOUND) { + return TRUE; + } else { + DebugMsg((DM_WARNING, TEXT("Delnode_Recurse: FindFirstFile failed. Error = %d"), + GetLastError())); + return FALSE; + } + } + + + do { + // + // Verbose output + // + + DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: FindFile found: <%s>"), + fd.cFileName)); + + // + // Check for "." and ".." + // + + if (!lstrcmpi(fd.cFileName, c_szDot)) { + continue; + } + + if (!lstrcmpi(fd.cFileName, c_szDotDot)) { + continue; + } + + + if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + + // + // Found a directory. + // + + if (!Delnode_Recurse(fd.cFileName)) { + FindClose(hFile); + return FALSE; + } + + if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { + fd.dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY; + SetFileAttributes (fd.cFileName, fd.dwFileAttributes); + } + + + if (!RemoveDirectory (fd.cFileName)) { + DebugMsg((DM_WARNING, TEXT("Delnode_Recurse: Failed to delete directory <%s>. Error = %d"), + fd.cFileName, GetLastError())); + } + + } else { + + // + // We found a file. Set the file attributes, + // and try to delete it. + // + + if ((fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) || + (fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) { + SetFileAttributes (fd.cFileName, FILE_ATTRIBUTE_NORMAL); + } + + if (!DeleteFile (fd.cFileName)) { + DebugMsg((DM_WARNING, TEXT("Delnode_Recurse: Failed to delete <%s>. Error = %d"), + fd.cFileName, GetLastError())); + } + + } + + + // + // Find the next entry + // + + } while (FindNextFile(hFile, &fd)); + + + // + // Close the search handle + // + + FindClose(hFile); + + + // + // Reset the working directory + // + + if (!SetCurrentDirectory (c_szDotDot)) { + DebugMsg((DM_WARNING, TEXT("Delnode_Recurse: Failed to reset current working directory. Error = %d"), GetLastError())); + return FALSE; + } + + + // + // Success. + // + + DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Leaving <%s>"), lpDir)); + + return TRUE; +} + + +//************************************************************* +// +// Delnode() +// +// Purpose: Recursive function that deletes files and +// directories. +// +// Parameters: lpDir - Directory +// +// Return: TRUE if successful +// FALSE if an error occurs +// +// Comments: +// +// History: Date Author Comment +// 6/23/95 ericflo Created +// +//************************************************************* + +BOOL Delnode (LPTSTR lpDir) +{ + TCHAR szCurWorkingDir[MAX_PATH]; + + if (GetCurrentDirectory(MAX_PATH, szCurWorkingDir)) { + + Delnode_Recurse (lpDir); + + SetCurrentDirectory (szCurWorkingDir); + + if (!RemoveDirectory (lpDir)) { + DebugMsg((DM_VERBOSE, TEXT("Delnode: Failed to delete directory <%s>. Error = %d"), + lpDir, GetLastError())); + return FALSE; + } + + + } else { + + DebugMsg((DM_WARNING, TEXT("Delnode: Failed to get current working directory. Error = %d"), GetLastError())); + return FALSE; + } + + return TRUE; + +} + +//************************************************************* +// +// CreateNestedDirectory() +// +// Purpose: Creates a subdirectory and all it's parents +// if necessary. +// +// Parameters: lpDirectory - Directory name +// lpSecurityAttributes - Security Attributes +// +// Return: > 0 if successful +// 0 if an error occurs +// +// Comments: +// +// History: Date Author Comment +// 8/08/95 ericflo Created +// +//************************************************************* + +UINT CreateNestedDirectory(LPCTSTR lpDirectory, LPSECURITY_ATTRIBUTES lpSecurityAttributes) +{ + TCHAR szDirectory[MAX_PATH]; + LPTSTR lpEnd; + + // + // Check for NULL pointer + // + + if (!lpDirectory || !(*lpDirectory)) { + DebugMsg((DM_WARNING, TEXT("CreateNestedDirectory: Received a NULL pointer."))); + return 0; + } + + + // + // First, see if we can create the directory without having + // to build parent directories. + // + + if (CreateDirectory (lpDirectory, lpSecurityAttributes)) { + return 1; + } + + // + // If this directory exists already, this is OK too. + // + + if (GetLastError() == ERROR_ALREADY_EXISTS) { + return ERROR_ALREADY_EXISTS; + } + + + // + // No luck, copy the string to a buffer we can munge + // + + lstrcpy (szDirectory, lpDirectory); + + + // + // Find the first subdirectory name + // + + lpEnd = szDirectory; + + if (szDirectory[1] == TEXT(':')) { + lpEnd += 3; + } else if (szDirectory[1] == TEXT('\\')) { + + // + // Skip the first two slashes + // + + lpEnd += 2; + + // + // Find the slash between the server name and + // the share name. + // + + while (*lpEnd && *lpEnd != TEXT('\\')) { + lpEnd++; + } + + if (!(*lpEnd)) { + return 0; + } + + // + // Skip the slash, and find the slash between + // the share name and the directory name. + // + + lpEnd++; + + while (*lpEnd && *lpEnd != TEXT('\\')) { + lpEnd++; + } + + if (!(*lpEnd)) { + return 0; + } + + // + // Leave pointer at the beginning of the directory. + // + + lpEnd++; + + + } else if (szDirectory[0] == TEXT('\\')) { + lpEnd++; + } + + while (*lpEnd) { + + while (*lpEnd && *lpEnd != TEXT('\\')) { + lpEnd++; + } + + if (*lpEnd == TEXT('\\')) { + *lpEnd = TEXT('\0'); + + if (!CreateDirectory (szDirectory, NULL)) { + + if (GetLastError() != ERROR_ALREADY_EXISTS) { + DebugMsg((DM_WARNING, TEXT("CreateNestedDirectory: CreateDirectory failed with %d."), GetLastError())); + return 0; + } + } + + *lpEnd = TEXT('\\'); + lpEnd++; + } + } + + + // + // Create the final directory + // + + if (CreateDirectory (szDirectory, lpSecurityAttributes)) { + return 1; + } + + if (GetLastError() == ERROR_ALREADY_EXISTS) { + return ERROR_ALREADY_EXISTS; + } + + + // + // Failed + // + + DebugMsg((DM_VERBOSE, TEXT("CreateNestedDirectory: Failed to create the directory with error %d."), GetLastError())); + + return 0; + +} + + +//************************************************************* +// +// GetProfilesDirectory() +// +// Purpose: Returns the location of the "profiles" directory +// +// Parameters: lpProfilesDir - Buffer to write result to +// lpcchSize - Size of the buffer in chars. +// +// Return: TRUE if successful +// FALSE if an error occurs +// +// Comments: If false is returned, lpcchSize holds the number of +// characters needed. +// +// History: Date Author Comment +// 9/18/95 ericflo Created +// +//************************************************************* + +BOOL WINAPI GetProfilesDirectory(LPTSTR lpProfilesDir, LPDWORD lpcchSize) +{ + TCHAR szDirectory[MAX_PATH]; + DWORD dwLength; + BOOL bRetVal = FALSE; + + ExpandEnvironmentStrings(PROFILES_DIR, szDirectory, MAX_PATH); + dwLength = lstrlen(szDirectory) + 1; + + if (lpProfilesDir) { + + if (*lpcchSize >= dwLength) { + lstrcpy (lpProfilesDir, szDirectory); + bRetVal = TRUE; + + } else { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + } + } + + + *lpcchSize = dwLength; + + return bRetVal; +} + + +//************************************************************* +// +// GetUserProfileDirectory() +// +// Purpose: Returns the root of the user's profile directory. +// +// Parameters: hToken - User's token +// lpProfileDir - Output buffer +// lpcchSize - Size of output buffer +// +// Return: TRUE if successful +// FALSE if an error occurs +// +// Comments: If false is returned, lpcchSize holds the number of +// characters needed. +// +// History: Date Author Comment +// 9/18/95 ericflo Created +// +//************************************************************* + +BOOL WINAPI GetUserProfileDirectory(HANDLE hToken, LPTSTR lpProfileDir, + LPDWORD lpcchSize) +{ + DWORD dwLength = MAX_PATH * sizeof(TCHAR); + DWORD dwType; + BOOL bRetVal = FALSE; + LPTSTR lpSidString; + TCHAR szBuffer[MAX_PATH]; + TCHAR szDirectory[MAX_PATH]; + HKEY hKey; + LONG lResult; + + + // + // Parameter check + // + + if (!hToken) { + return FALSE; + } + + + // + // Retrieve the user's sid string + // + + lpSidString = GetSidString(hToken); + + if (!lpSidString) { + return FALSE; + } + + + // + // Check the registry + // + + lstrcpy(szBuffer, PROFILE_LIST_PATH); + lstrcat(szBuffer, TEXT("\\")); + lstrcat(szBuffer, lpSidString); + + lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ, + &hKey); + + if (lResult != ERROR_SUCCESS) { + DeleteSidString(lpSidString); + return FALSE; + } + + lResult = RegQueryValueEx(hKey, + PROFILE_IMAGE_VALUE_NAME, + NULL, + &dwType, + (LPBYTE) szBuffer, + &dwLength); + + if (lResult != ERROR_SUCCESS) { + RegCloseKey (hKey); + DeleteSidString(lpSidString); + return FALSE; + } + + + // + // Clean up + // + + RegCloseKey(hKey); + DeleteSidString(lpSidString); + + + + // + // Expand and get the length of string + // + + ExpandEnvironmentStrings(szBuffer, szDirectory, MAX_PATH); + + dwLength = lstrlen(szDirectory) + 1; + + + // + // Save the string if appropriate + // + + if (lpProfileDir) { + + if (*lpcchSize >= dwLength) { + lstrcpy (lpProfileDir, szDirectory); + bRetVal = TRUE; + + } else { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + } + } + + + *lpcchSize = dwLength; + + return bRetVal; +} + +//************************************************************* +// +// StringToInt() +// +// Purpose: Converts a string to an integer +// +// Parameters: lpNum - Number to convert +// +// Return: The number +// +// Comments: +// +// History: Date Author Comment +// 10/3/95 ericflo Created +// +//************************************************************* + +int StringToInt(LPTSTR lpNum) +{ + int i = 0; + BOOL bNeg = FALSE; + + if (*lpNum == TEXT('-')) { + bNeg = TRUE; + lpNum++; + } + + while (*lpNum >= TEXT('0') && *lpNum <= TEXT('9')) { + i *= 10; + i += (int)(*lpNum-TEXT('0')); + lpNum++; + } + + if (bNeg) { + i *= -1; + } + + return(i); +} + +//************************************************************* +// +// RegDelnodeRecurse() +// +// Purpose: Deletes a registry key and all it's subkeys / values. +// Called by RegDelnode +// +// Parameters: hKeyRoot - Root key +// lpSubKey - SubKey to delete +// +// Return: TRUE if successful +// FALSE if an error occurs +// +// Comments: +// +// History: Date Author Comment +// 10/3/95 ericflo Created +// +//************************************************************* + +BOOL RegDelnodeRecurse (HKEY hKeyRoot, LPTSTR lpSubKey) +{ + LPTSTR lpEnd; + LONG lResult; + DWORD dwSize; + TCHAR szName[MAX_PATH]; + HKEY hKey; + FILETIME ftWrite; + + // + // First, see if we can delete the key without having + // to recurse. + // + + + lResult = RegDeleteKey(hKeyRoot, lpSubKey); + + if (lResult == ERROR_SUCCESS) { + return TRUE; + } + + + lResult = RegOpenKeyEx (hKeyRoot, lpSubKey, 0, KEY_READ, &hKey); + + if (lResult != ERROR_SUCCESS) { + return FALSE; + } + + + lpEnd = CheckSlash(lpSubKey); + + // + // Enumerate the keys + // + + dwSize = MAX_PATH; + lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, + NULL, NULL, &ftWrite); + + if (lResult == ERROR_SUCCESS) { + + do { + + lstrcpy (lpEnd, szName); + + if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) { + break; + } + + // + // Enumerate again + // + + dwSize = MAX_PATH; + + lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, + NULL, NULL, &ftWrite); + + + } while (lResult == ERROR_SUCCESS); + } + + lpEnd--; + *lpEnd = TEXT('\0'); + + + RegCloseKey (hKey); + + + // + // Try again to delete the key + // + + lResult = RegDeleteKey(hKeyRoot, lpSubKey); + + if (lResult == ERROR_SUCCESS) { + return TRUE; + } + + return FALSE; +} + +//************************************************************* +// +// RegDelnode() +// +// Purpose: Deletes a registry key and all it's subkeys / values +// +// Parameters: hKeyRoot - Root key +// lpSubKey - SubKey to delete +// +// Return: TRUE if successful +// FALSE if an error occurs +// +// Comments: +// +// History: Date Author Comment +// 10/3/95 ericflo Created +// +//************************************************************* + +BOOL RegDelnode (HKEY hKeyRoot, LPTSTR lpSubKey) +{ + TCHAR szDelKey[2 * MAX_PATH]; + + + lstrcpy (szDelKey, lpSubKey); + + return RegDelnodeRecurse(hKeyRoot, szDelKey); + +} + +//************************************************************* +// +// DeleteAllValues () +// +// Purpose: Deletes all values under specified key +// +// Parameters: hKey - Key to delete values from +// +// Return: +// +// Comments: +// +// History: Date Author Comment +// 9/14/95 ericflo Ported +// +//************************************************************* + +VOID DeleteAllValues(HKEY hKey) +{ + TCHAR ValueName[MAX_PATH+1]; + DWORD dwSize = MAX_PATH+1; + + while (RegEnumValue(hKey, 0, ValueName, &dwSize, + NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { + + if (RegDeleteValue(hKey, ValueName) != ERROR_SUCCESS) { + return; + } + + dwSize = MAX_PATH+1; + } +} + +//************************************************************* +// +// OpenHKeyCurrentUser() +// +// Purpose: Opens HKEY_CURRENT_USER to point at the current logged +// on user's profile. +// +// Parameters: lpProfile - Profile Information +// +// Return: TRUE if successful +// FALSE if an error occurs +// +// Comments: +// +// History: Date Author Comment +// 10/13/95 ericflo Ported +// +//************************************************************* + +BOOL OpenHKeyCurrentUser(LPPROFILE lpProfile) +{ + + // + // Make sure HKEY_CURRENT_USER is closed before + // remapping it. + // + + try { + + RegCloseKey(HKEY_CURRENT_USER); + + } except(EXCEPTION_EXECUTE_HANDLER) {}; + + + // + // Impersonate the user + // + + if (!ImpersonateLoggedOnUser(lpProfile->hToken)) { + DebugMsg((DM_WARNING, TEXT("OpenHKeyCurrentUser: Failed to impersonate user"))); + return FALSE; + } + + + // + // Access the registry to force HKEY_CURRENT_USER to be re-opened + // + + RegEnumKey(HKEY_CURRENT_USER, 0, NULL, 0); + + + // + // Revert to being 'ourself' + // + + if (!RevertToSelf()) { + DebugMsg((DM_WARNING, TEXT("OpenHKeyCurrentUser: Failed to revert to self"))); + } + + return TRUE; +} + +//************************************************************* +// +// CloseHKeyCurrentUser() +// +// Purpose: Closes HKEY_CURRENT_USER +// +// Parameters: lpProfile - Profile Information +// +// Return: void +// +// Comments: +// +// History: Date Author Comment +// 10/13/95 ericflo Ported +// +//************************************************************* + +VOID CloseHKeyCurrentUser(LPPROFILE lpProfile) +{ + RegCloseKey(HKEY_CURRENT_USER); +} + +//************************************************************* +// +// MakeFileSecure() +// +// Purpose: Sets the attributes on the file so only Administrators +// and the OS can delete it. Everyone else has read +// permission only. +// +// Parameters: lpFile - File to set security on +// +// Return: (BOOL) TRUE if successful +// FALSE if an error occurs +// +// Comments: +// +// History: Date Author Comment +// 11/6/95 ericflo Created +// +//************************************************************* + +BOOL MakeFileSecure (LPTSTR lpFile) +{ + SECURITY_DESCRIPTOR sd; + SECURITY_ATTRIBUTES sa; + SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY; + SID_IDENTIFIER_AUTHORITY authWorld = SECURITY_WORLD_SID_AUTHORITY; + PACL pAcl = NULL; + PSID psidSystem = NULL, psidAdmin = NULL, psidEveryone = NULL; + DWORD cbAcl, aceIndex; + ACE_HEADER * lpAceHeader; + BOOL bRetVal = FALSE; + + + // + // Get the system sid + // + + if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0, &psidSystem)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to initialize system sid. Error = %d"), GetLastError())); + goto Exit; + } + + + // + // Get the Admin sid + // + + if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, 0, 0, + 0, 0, 0, 0, &psidAdmin)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to initialize admin sid. Error = %d"), GetLastError())); + goto Exit; + } + + + // + // Get the World sid + // + + if (!AllocateAndInitializeSid(&authWorld, 1, SECURITY_WORLD_RID, + 0, 0, 0, 0, 0, 0, 0, &psidEveryone)) { + + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to initialize world sid. Error = %d"), GetLastError())); + goto Exit; + } + + + // + // Allocate space for the ACL + // + + cbAcl = (3 * GetLengthSid (psidSystem)) + + (3 * GetLengthSid (psidAdmin)) + sizeof(ACL) + + (6 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))); + + + pAcl = (PACL) GlobalAlloc(GMEM_FIXED, cbAcl); + if (!pAcl) { + goto Exit; + } + + + if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to initialize acl. Error = %d"), GetLastError())); + goto Exit; + } + + + + // + // Add Aces. Non-inheritable ACEs first + // + + aceIndex = 0; + if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, psidSystem)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to add ace (%d). Error = %d"), aceIndex, GetLastError())); + goto Exit; + } + + + aceIndex++; + if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, psidAdmin)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to add ace (%d). Error = %d"), aceIndex, GetLastError())); + goto Exit; + } + + + aceIndex++; + if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_READ | GENERIC_EXECUTE, psidEveryone)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to add ace (%d). Error = %d"), aceIndex, GetLastError())); + goto Exit; + } + + + + // + // Now the inheritable ACEs + // + + aceIndex++; + if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidSystem)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to add ace (%d). Error = %d"), aceIndex, GetLastError())); + goto Exit; + } + + if (!GetAce(pAcl, aceIndex, &lpAceHeader)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to get ace (%d). Error = %d"), aceIndex, GetLastError())); + goto Exit; + } + + lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); + + + aceIndex++; + if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidAdmin)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to add ace (%d). Error = %d"), aceIndex, GetLastError())); + goto Exit; + } + + if (!GetAce(pAcl, aceIndex, &lpAceHeader)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to get ace (%d). Error = %d"), aceIndex, GetLastError())); + goto Exit; + } + + lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); + + + aceIndex++; + if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_READ | GENERIC_EXECUTE, psidEveryone)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to add ace (%d). Error = %d"), aceIndex, GetLastError())); + goto Exit; + } + + if (!GetAce(pAcl, aceIndex, &lpAceHeader)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to get ace (%d). Error = %d"), aceIndex, GetLastError())); + goto Exit; + } + + lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); + + + // + // Put together the security descriptor + // + + if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to initialize security descriptor. Error = %d"), GetLastError())); + goto Exit; + } + + + if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: Failed to set security descriptor dacl. Error = %d"), GetLastError())); + goto Exit; + } + + + // + // Set the security + // + + if (SetFileSecurity (lpFile, DACL_SECURITY_INFORMATION, &sd)) { + bRetVal = TRUE; + } else { + DebugMsg((DM_WARNING, TEXT("MakeFileSecure: SetFileSecurity failed. Error = %d"), GetLastError())); + } + + + +Exit: + + if (psidSystem) { + FreeSid(psidSystem); + } + + if (psidAdmin) { + FreeSid(psidAdmin); + } + + + if (psidEveryone) { + FreeSid(psidEveryone); + } + + + if (pAcl) { + GlobalFree (pAcl); + } + + return bRetVal; +} + +//************************************************************* +// +// GetProgramsDirectory() +// +// Purpose: Retrieves the programs directory for the current +// user, or returns Default User's if not found. +// +// Parameters: bCommonGroup - Common or personal +// lpDirectory - Result +// +// Return: TRUE if successful +// FALSE if an error occurs +// +// Comments: lpDirectory is assumed to be MAX_PATH chars long +// +// History: Date Author Comment +// 10/20/95 ericflo Created +// +//************************************************************* + +BOOL GetProgramsDirectory (BOOL bCommonGroup, LPTSTR lpDirectory) +{ + LONG lResult; + HKEY hKey; + DWORD dwType, dwSize; + TCHAR szDirectory[MAX_PATH]; + UINT uID; + BOOL bRetVal = FALSE; + + + // + // Open the User Shell Folders in the registry + // + + + lResult = RegOpenKeyEx (HKEY_CURRENT_USER, USER_SHELL_FOLDER, 0, + KEY_READ, &hKey); + + + if (lResult != ERROR_SUCCESS) { + DebugMsg((DM_WARNING, TEXT("GetProgramsDirectory: Failed to open registry. %d"), lResult)); + goto Exit; + } + + + // + // Now query for the programs directory + // + + dwSize = MAX_PATH * sizeof(TCHAR); + szDirectory[0] = TEXT('\0'); + + if (bCommonGroup) { + + lResult = RegQueryValueEx (hKey, c_CommonShellFolders[2].lpFolderName, + NULL, &dwType, (LPBYTE) szDirectory, &dwSize); + } else { + + lResult = RegQueryValueEx (hKey, c_ShellFolders[10].lpFolderName, + NULL, &dwType, (LPBYTE) szDirectory, &dwSize); + } + + + RegCloseKey(hKey); + + + if (lResult != ERROR_SUCCESS) { + DebugMsg((DM_WARNING, TEXT("GetProgramsDirectory: Failed to query for registry value. %d"), lResult)); + goto Exit; + } + + + // + // Did we find anything? + // + + if (szDirectory[0] == TEXT('\0')) { + DebugMsg((DM_WARNING, TEXT("GetProgramsDirectory: NULL special folder name"))); + goto Exit; + } + + + // + // Save the result + // + + + if (ExpandEnvironmentStrings(szDirectory, lpDirectory, MAX_PATH)) { + bRetVal = TRUE; + } + + +Exit: + + if (!bRetVal) { + + // + // Load the default programs location + // + + if (bCommonGroup) { + uID = IDS_COMMON_PROGRAMS; + } else { + uID = IDS_DEFAULT_PROGRAMS; + } + + DebugMsg((DM_VERBOSE, TEXT("GetProgramsDirectory: Loading Default User programs dir !!!"))); + + if (LoadString(g_hDllInstance, uID, szDirectory, MAX_PATH)) { + + if (ExpandEnvironmentStrings(szDirectory, lpDirectory, MAX_PATH)) { + bRetVal = TRUE; + } + } + } + + + return bRetVal; + +} + +//************************************************************* +// +// GetDesktopDirectory() +// +// Purpose: Retrieves the Desktop directory for the current +// user, or returns Default User's if not found. +// +// Parameters: bCommonGroup - Common or personal +// lpDirectory - Result +// +// Return: TRUE if successful +// FALSE if an error occurs +// +// Comments: lpDirectory is assumed to be MAX_PATH chars long +// +// History: Date Author Comment +// 4/2/96 ericflo Created +// +//************************************************************* + +BOOL GetDesktopDirectory (BOOL bCommonGroup, LPTSTR lpDirectory) +{ + LONG lResult; + HKEY hKey; + DWORD dwType, dwSize; + TCHAR szDirectory[MAX_PATH]; + UINT uID; + BOOL bRetVal = FALSE; + + + // + // Open the User Shell Folders in the registry + // + + + lResult = RegOpenKeyEx (HKEY_CURRENT_USER, USER_SHELL_FOLDER, 0, + KEY_READ, &hKey); + + + if (lResult != ERROR_SUCCESS) { + goto Exit; + } + + + // + // Now query for the Desktop directory + // + + dwSize = MAX_PATH * sizeof(TCHAR); + szDirectory[0] = TEXT('\0'); + + if (bCommonGroup) { + + lResult = RegQueryValueEx (hKey, c_CommonShellFolders[0].lpFolderName, + NULL, &dwType, (LPBYTE) szDirectory, &dwSize); + } else { + + lResult = RegQueryValueEx (hKey, c_ShellFolders[1].lpFolderName, + NULL, &dwType, (LPBYTE) szDirectory, &dwSize); + } + + + RegCloseKey(hKey); + + + if (lResult != ERROR_SUCCESS) { + goto Exit; + } + + + // + // Did we find anything? + // + + if (szDirectory[0] == TEXT('\0')) { + goto Exit; + } + + + // + // Save the result + // + + + if (ExpandEnvironmentStrings(szDirectory, lpDirectory, MAX_PATH)) { + bRetVal = TRUE; + } + + +Exit: + + if (!bRetVal) { + + // + // Load the default Desktop location + // + + if (bCommonGroup) { + uID = IDS_COMMON_DESKTOP; + } else { + uID = IDS_DEFAULT_DESKTOP; + } + + if (LoadString(g_hDllInstance, uID, szDirectory, MAX_PATH)) { + + if (ExpandEnvironmentStrings(szDirectory, lpDirectory, MAX_PATH)) { + bRetVal = TRUE; + } + } + } + + + return bRetVal; + +} + + +//************************************************************* +// +// CenterWindow() +// +// Purpose: Centers a window on the screen +// +// Parameters: hwnd - window handle to center +// +// Return: void +// +// Comments: +// +// History: Date Author Comment +// 2/21/96 ericflo Ported +// +//************************************************************* + +void CenterWindow (HWND hwnd) +{ + RECT rect; + LONG dx, dy; + LONG dxParent, dyParent; + LONG Style; + + // Get window rect + GetWindowRect(hwnd, &rect); + + dx = rect.right - rect.left; + dy = rect.bottom - rect.top; + + // Get parent rect + Style = GetWindowLong(hwnd, GWL_STYLE); + if ((Style & WS_CHILD) == 0) { + + // Return the desktop windows size (size of main screen) + dxParent = GetSystemMetrics(SM_CXSCREEN); + dyParent = GetSystemMetrics(SM_CYSCREEN); + } else { + HWND hwndParent; + RECT rectParent; + + hwndParent = GetParent(hwnd); + if (hwndParent == NULL) { + hwndParent = GetDesktopWindow(); + } + + GetWindowRect(hwndParent, &rectParent); + + dxParent = rectParent.right - rectParent.left; + dyParent = rectParent.bottom - rectParent.top; + } + + // Centre the child in the parent + rect.left = (dxParent - dx) / 2; + rect.top = (dyParent - dy) / 3; + + // Move the child into position + SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, 0, 0, SWP_NOSIZE); +} + +//************************************************************* +// +// UnExpandSysRoot() +// +// Purpose: Unexpands the given path/filename to have %systemroot% +// if appropriate +// +// Parameters: lpFile - File to check +// lpResult - Result buffer (MAX_PATH chars in size) +// +// Return: TRUE if successful +// FALSE if an error occurs +// +// Comments: +// +// History: Date Author Comment +// 2/23/96 ericflo Created +// +//************************************************************* + +BOOL UnExpandSysRoot(LPCTSTR lpFile, LPTSTR lpResult) +{ + TCHAR szSysRoot[MAX_PATH]; + LPTSTR lpFileName; + DWORD dwSysLen; + + + // + // Verbose Output + // + + DebugMsg((DM_VERBOSE, TEXT("UnExpandSysRoot: Entering with <%s>"), + lpFile ? lpFile : TEXT("NULL"))); + + + if (!lpFile || !*lpFile) { + DebugMsg((DM_VERBOSE, TEXT("UnExpandSysRoot: lpFile is NULL, setting lpResult to a null string"))); + *lpResult = TEXT('\0'); + return TRUE; + } + + + // + // If the first part of lpFile is the expanded value of %SystemRoot% + // then we want to un-expand the environment variable. + // + + ExpandEnvironmentStrings (TEXT("%SystemRoot%"), szSysRoot, MAX_PATH); + dwSysLen = lstrlen(szSysRoot); + + + // + // Make sure the source is long enough + // + + if ((DWORD)lstrlen(lpFile) < dwSysLen) { + lstrcpy (lpResult, lpFile); + return TRUE; + } + + + if (CompareString (LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, + szSysRoot, dwSysLen, + lpFile, dwSysLen) == 2) { + + // + // The szReturn buffer starts with %systemroot%. + // Actually insert %systemroot% in the result buffer. + // + + lstrcpy (lpResult, TEXT("%SystemRoot%")); + lstrcat (lpResult, (lpFile + dwSysLen)); + + + } else { + + // + // The szReturn buffer does not start with %systemroot% + // just copy in the original string. + // + + lstrcpy (lpResult, lpFile); + } + + + DebugMsg((DM_VERBOSE, TEXT("UnExpandSysRoot: Leaving with <%s>"), lpResult)); + + return TRUE; +} + +//************************************************************* +// +// AllocAndExpandEnvironmentStrings() +// +// Purpose: Allocates memory for and returns pointer to buffer containing +// the passed string expanded. +// +// Parameters: lpszSrc - unexpanded string +// +// Return: Pointer to expanded string +// NULL if an error occurs +// +// Comments: +// +// History: Date Author Comment +// 6/21/96 ericflo Ported +// +//************************************************************* + +LPTSTR AllocAndExpandEnvironmentStrings(LPCTSTR lpszSrc) +{ + LPTSTR String; + LONG LengthAllocated; + LONG LengthCopied; + + // + // Pick a random buffer length, if it's not big enough reallocate + // it and try again until it is. + // + + LengthAllocated = lstrlen(lpszSrc) + TYPICAL_STRING_LENGTH; + + String = LocalAlloc(LPTR, LengthAllocated * sizeof(TCHAR)); + if (String == NULL) { + DebugMsg((DM_WARNING, TEXT("AllocAndExpandEnvironmentStrings: Failed to allocate %d bytes for string"), LengthAllocated * sizeof(TCHAR))); + return(NULL); + } + + while (TRUE) { + + LengthCopied = ExpandEnvironmentStrings( lpszSrc, + String, + LengthAllocated + ); + if (LengthCopied == 0) { + DebugMsg((DM_WARNING, TEXT("AllocAndExpandEnvironmentStrings: ExpandEnvironmentStrings failed, error = %d"), GetLastError())); + Free(String); + String = NULL; + break; + } + + // + // If the buffer was too small, make it bigger and try again + // + + if (LengthCopied > LengthAllocated) { + + String = LocalReAlloc(String, LengthCopied * sizeof(TCHAR), LMEM_MOVEABLE); + LengthAllocated = LengthCopied; + if (String == NULL) { + DebugMsg((DM_WARNING, TEXT("AllocAndExpandEnvironmentStrings: Failed to reallocate %d bytes for string"), LengthAllocated * sizeof(TCHAR))); + break; + } + + // + // Go back and try to expand the string again + // + + } else { + + // + // Success! + // + + break; + } + + } + + return(String); +} |