2020-09-30 17:12:29 +02:00

1646 lines
37 KiB
C

//*************************************************************
//
// 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);
}