//TODO: Expand this function to allow for artificially elevated limited users. // For example, a limited user given the permission to write to HKLM // (something that is normally forbidden). bool OnlyUpdatingLocalUser() { // if installing // - system folders // - non-user registry // - Windows Services // - COM files // then return false // Also note how we're excluding the "BaseDir". // This is because the base directory may or may not be in the userprofile // directory (or otherwise writable by the user), thus it needs a separate check. // Ditto for the "client.wyc" file. if (((updateFrom.InstallingTo | InstallingTo.BaseDir) ^ InstallingTo.BaseDir) != 0) { return(false); } string userProfileFolder = SystemFolders.GetUserProfile(); // if the basedir isn't in the userprofile folder (C:\Users\UserName) // OR // if the folder isn't in the full control of the current user // THEN // we're not "only updating the local user if ((updateFrom.InstallingTo & InstallingTo.BaseDir) != 0 && !(SystemFolders.IsDirInDir(userProfileFolder, baseDirectory) || HaveFolderPermissions(baseDirectory))) { return(false); } return(true); }
//TODO: Expand this function to allow for artificially elevated limited users. // For example, a limited user given the permission to write to HKLM // (something that is normally forbidden). bool OnlyUpdatingLocalUser() { // if installing // - system folders // - non-user registry // - Windows Services // - COM files // then return false // Also note how we're excluding the "BaseDir". // This is because the base directory may or may not be in the userprofile // directory (or otherwise writable by the user), thus it needs a separate check. // Ditto for the "client.wyc" file. if (((updateFrom.InstallingTo | InstallingTo.BaseDir) ^ InstallingTo.BaseDir) != 0) { return(false); } string userProfileFolder = SystemFolders.GetUserProfile(); // if the basedir isn't in the userprofile folder (C:\Users\UserName) // OR // if the folder isn't in the full control of the current user // THEN // we're not "only updating the local user if ((updateFrom.InstallingTo & InstallingTo.BaseDir) != 0 && !(SystemFolders.IsDirInDir(userProfileFolder, baseDirectory) || HaveFolderPermissions(baseDirectory))) { return(false); } // if the client data file isn't in the userprofile folder (or otherwise writable) // then bail out. if (!(SystemFolders.IsFileInDirectory(userProfileFolder, clientFileLoc) || HaveFolderPermissions(Path.GetDirectoryName(clientFileLoc)))) { return(false); } // when self-updating, if this client isn't in the userprofile folder if ((SelfUpdateState == SelfUpdateState.WillUpdate || SelfUpdateState == SelfUpdateState.FullUpdate || SelfUpdateState == SelfUpdateState.Extracted) && !(SystemFolders.IsFileInDirectory(userProfileFolder, VersionTools.SelfLocation) || HaveFolderPermissions(Path.GetDirectoryName(VersionTools.SelfLocation)))) { return(false); } return(true); }
/// <summary>Gets or creates the cache folder for a GUID.</summary> /// <param name="guid">The GUID.</param> /// <returns>The directory to the cache folder</returns> static string GetCacheFolder(string guid) { string userprofile = SystemFolders.GetUserProfile(); // if getting the userprofile folder fails, then try the app data folder if (string.IsNullOrEmpty(userprofile)) { userprofile = SystemFolders.GetCurrentUserAppData(); } if (string.IsNullOrEmpty(userprofile)) { throw new Exception("Failed to retrieve the user profile folder."); } // C:\Users\USERNAME\wc string temp = Path.Combine(userprofile, "wc"); // if the folder temp folder doesn't exist, create the folder with hidden attributes if (!Directory.Exists(temp)) { Directory.CreateDirectory(temp); File.SetAttributes(temp, FileAttributes.System | FileAttributes.Hidden); } string fullGuidFolder = Path.Combine(temp, guid); // Workaround for the "pyramid of death" bug. // Note: This still doesn't address the root cause of the "pyramid of death" // namely, why aren't the folders being cleaned up on the failure of wyUpdate? // Perhaps it's a crashing bug. Further investigation is needed. We need to look into // possible causes for cached files being left around. This problem was first spotted // when a user's app crashed when they were debugging. It was crashing over and over again if (Directory.Exists(fullGuidFolder)) { string guidFile = Path.Combine(fullGuidFolder, guid); // if the GUID file doesn't already exist then the cache is busted. if (!File.Exists(guidFile)) { // delete every file and folder in the directory because it's an invalid cache string[] obs = Directory.GetDirectories(fullGuidFolder); // remove all directories foreach (var dir in obs) { Directory.Delete(dir, true); } obs = Directory.GetFiles(fullGuidFolder); // remove all the files foreach (var file in obs) { File.Delete(file); } // create the blank GUID file using (File.Create(guidFile)); } return(fullGuidFolder); } // try to create the smallest possible folder name (using the GUID) string closestMatch = null; string[] dirs = Directory.GetDirectories(temp); // loop through the directories - stop at the first partial match this GUID for (int i = 0; i < dirs.Length; i++) { string name = Path.GetFileName(dirs[i]); if (string.IsNullOrEmpty(name) || guid.IndexOf(name) != 0) { continue; } // see if the partial-matching folder contains an empty GUID file if (File.Exists(Path.Combine(dirs[i], guid))) { return(dirs[i]); } closestMatch = name; } // the folder doesn't exist, so we'll create it string guidCacheFolder = Path.Combine(temp, guid.Substring(0, closestMatch == null ? 1 : closestMatch.Length + 1)); Directory.CreateDirectory(guidCacheFolder); // create the blank GUID file using (File.Create(Path.Combine(guidCacheFolder, guid))); return(guidCacheFolder); }