/// <summary> /// For a client sync request, gathers applicable software updates that the client does not have yet /// </summary> /// <param name="installedNonLeaf">List of non leaf updates installed on the client</param> /// <param name="otherCached">List of other updates known to the client</param> /// <param name="response">The response to append new updates to</param> /// <param name="updatesAdded">On return: true of updates were added to the response, false otherwise</param> private void AddMissingSoftwareUpdatesToSyncUpdatesResponse(List <Guid> installedNonLeaf, List <Guid> otherCached, SyncInfo response, out bool updatesAdded) { var allMissingApplicableUpdates = SoftwareLeafUpdateGuids .Except(installedNonLeaf) // Do not resend installed updates .Except(otherCached) // Do not resend other client known updates .Select(guid => IdToFullIdentityMap[guid]) // Map the GUID to a fully qualified identity .Select(id => MetadataSource.UpdatesIndex[id]) // Select the software update by identity .OfType <SoftwareUpdate>() .Where(u => !u.IsSuperseded && u.IsApplicable(installedNonLeaf) && !u.IsBundle); // Remove superseded, not applicable and bundles var unapprovedMissingUpdates = allMissingApplicableUpdates .Where(u => !ApprovedSoftwareUpdates.Contains(u.Identity) && (!u.IsBundled || !u.BundleParent.Any(i => ApprovedSoftwareUpdates.Contains(i)))); if (unapprovedMissingUpdates.Count() > 0) { OnUnApprovedSoftwareUpdatesRequested?.Invoke(unapprovedMissingUpdates); } var missingApplicableUpdates = allMissingApplicableUpdates .Where(u => ApprovedSoftwareUpdates.Contains(u.Identity) || (u.IsBundled && u.BundleParent.Any(i => ApprovedSoftwareUpdates.Contains(i)))) // The update is approved or it's part of a bundle that is approved .Take(MaxUpdatesInResponse + 1) // Only take the maximum number of updates allowed + 1 (to see if we truncated) .ToList(); response.Truncated = missingApplicableUpdates.Count > MaxUpdatesInResponse; if (missingApplicableUpdates.Count > 0) { response.NewUpdates = CreateUpdateInfoListFromSoftwareUpdate(missingApplicableUpdates).ToArray(); updatesAdded = true; } else { updatesAdded = false; } }
/// <summary> /// Handle driver sync requests /// </summary> /// <param name="parameters"></param> /// <returns></returns> private Task <SyncInfo> DoDriversSync(SyncUpdateParameters parameters) { // Get list of driver updates known to the client var cachedDrivers = GetUpdateIdentitiesFromClientIndexes(parameters.CachedDriverIDs); // Get list of installed non-leaf updates. Used to match pre-requisites for driver updates var installedNonLeafUpdatesGuids = GetInstalledNotLeafGuidsFromSyncParameters(parameters); // Initialize the response var syncResult = new SyncInfo() { NewCookie = new Cookie() { Expiration = DateTime.Now.AddDays(5), EncryptedData = new byte[12] }, DriverSyncNotNeeded = "false", Truncated = false }; List <Guid> computerHardwareIds = parameters.ComputerSpec.HardwareIDs != null?parameters.ComputerSpec.HardwareIDs.ToList() : new List <Guid>(); List <UpdateInfo> driverUpdates = new List <UpdateInfo>(); List <Update> unapprovedDriversMatched = new List <Update>(); // Go through all client reported devices foreach (var device in parameters.SystemSpec) { // Combine the list hardware ids and compatible hwids; we will // match them in this order, from specific to less specific var hardwareIdsToMatch = new List <string>(device.HardwareIDs); if (device.CompatibleIDs != null) { hardwareIdsToMatch.AddRange(device.CompatibleIDs); } // Get best match driver var driverMatchResult = MetadataSource.MatchDriver(hardwareIdsToMatch, computerHardwareIds, installedNonLeafUpdatesGuids); // If we have a match and the client does not have it, add it to the list if (driverMatchResult != null && !cachedDrivers.Contains(driverMatchResult.Driver.Identity) && !IsInstalledDriverBetterMatch(device.installedDriver, driverMatchResult, hardwareIdsToMatch, computerHardwareIds)) { if (ApprovedSoftwareUpdates.Contains(driverMatchResult.Driver.Identity)) { // Get core XML fragment for driver update var coreXml = GetCoreFragment(driverMatchResult.Driver.Identity); driverUpdates.Add(new UpdateInfo() { Deployment = new Deployment() { Action = DeploymentAction.Install, ID = 25000, AutoDownload = "0", AutoSelect = "0", SupersedenceBehavior = "0", IsAssigned = true, LastChangeTime = "2019-08-06" }, ID = IdToRevisionMap[driverMatchResult.Driver.Identity.ID], IsLeaf = true, Xml = coreXml, IsShared = false, Verification = null }); } else { unapprovedDriversMatched.Add(driverMatchResult.Driver); } } // Stop matching if we have max updates already if (driverUpdates.Count == MaxUpdatesInResponse) { syncResult.Truncated = true; break; } } if (unapprovedDriversMatched.Count > 0) { OnUnApprovedDriverUpdatesRequested?.Invoke(unapprovedDriversMatched); } syncResult.NewUpdates = driverUpdates.ToArray(); return(Task.FromResult(syncResult)); }