예제 #1
0
파일: Coloma.cs 프로젝트: stanleyhon/Coloma
        private static void SortandFix(List <ColomaEvent> eventlist, bool setuplog)
        {
            uint r = 11;

            if (!setuplog)
            {
                WindowsVersion.WindowsVersionInfo wvi = new WindowsVersion.WindowsVersionInfo();
                WindowsVersion.GetWindowsBuildandRevision(wvi);
                r = wvi.revision;
            }

            // sort the list by date
            eventlist.Sort();

            foreach (ColomaEvent evt in eventlist)
            {
                if (evt.Logname == "Setup")
                {
                    r = evt.Revision;
                }
                else
                {
                    evt.Revision = r;
                }
            }
        }
예제 #2
0
파일: Coloma.cs 프로젝트: stanleyhon/Coloma
        private static bool AddSetupLogToList(List <KBRevision> kbrlist, List <ColomaEvent> list, DateTime dt)
        {
            // this retrieves the build.revision and branch for the current client
            WindowsVersion.WindowsVersionInfo wvi = new WindowsVersion.WindowsVersionInfo();
            WindowsVersion.GetWindowsBuildandRevision(wvi);
            uint revision = wvi.revision;
            bool setuplog = false;

            EventLogQuery query = new EventLogQuery("Setup", PathType.LogName);

            query.ReverseDirection = false;
            EventLogReader reader = new EventLogReader(query);

            EventRecord entry;

            while ((entry = reader.ReadEvent()) != null)
            {
                if ((entry.Level == (byte)StandardEventLevel.Critical) ||
                    (entry.Level == (byte)StandardEventLevel.Error) ||
                    (entry.Level == (byte)StandardEventLevel.Warning) ||
                    (entry.Id == 2))
                {
                    string msg = CleanUpMessage(entry.FormatDescription());

                    if (entry.Id == 2)
                    {
                        // this is a KB installed message, figure out which KB it is and update the revision of that entry
                        string kb = "KB";
                        int    i  = msg.IndexOf(kb);
                        setuplog = true;

                        if (-1 != i)
                        {
                            // we found the kb article
                            kb = msg.Substring(i, 9);

                            foreach (KBRevision rev in kbrlist)
                            {
                                if (rev.Kb == kb)
                                {
                                    revision = rev.Revision;
                                }
                            }
                        }
                    }
                    list.Add(new ColomaEvent(wvi.branch, wvi.build, revision, entry.MachineName, DeviceId,
                                             Environment.UserName, "Setup", entry.LevelDisplayName, entry.Id,
                                             entry.TimeCreated.GetValueOrDefault(), entry.ProviderName, msg));
                }
            }
            return(setuplog);
        }
예제 #3
0
        static void AddStandardLogToList(EventLog log, List <ColomaEvent> list, DateTime dt)
        {
            WindowsVersion.WindowsVersionInfo wvi = new WindowsVersion.WindowsVersionInfo();
            WindowsVersion.GetWindowsBuildandRevision(wvi);

            foreach (EventLogEntry entry in log.Entries)
            {
                if (entry.TimeGenerated > dt)
                {
                    if ((entry.EntryType == EventLogEntryType.Error) ||
                        (entry.EntryType == EventLogEntryType.Warning))
                    {
                        string msg = CleanUpMessage(entry.Message);
                        list.Add(new ColomaEvent(wvi.branch, wvi.build, 0, entry.MachineName, Environment.UserName, log.LogDisplayName, entry.EntryType.ToString(), entry.TimeGenerated, entry.Source, msg));
                    }
                }
            }
        }
예제 #4
0
파일: Coloma.cs 프로젝트: Robo210/Coloma
        private static void AddLogToList(List<ColomaEvent> list, DateTime dt, Dictionary<string, KBRevision> installedUpdates)
        {
            // this retrieves the build.revision and branch for the current client
            WindowsVersion.WindowsVersionInfo wvi = new WindowsVersion.WindowsVersionInfo();
            WindowsVersion.GetWindowsBuildandRevision(wvi);

            FirstBuild firstBuildEvent = new FirstBuild { index = 0, build = wvi.build };

            KBRevision currentKb = new KBRevision();
            uint currentBuild = wvi.build;

            Guid servicingProvider = new Guid("BD12F3B8-FC40-4A61-A307-B7A013A069C1");
            string structuredQuery = string.Format(System.Globalization.CultureInfo.InvariantCulture, Coloma.structuredQueryTemplate, dt.ToUniversalTime());

            EventLogQuery query = new EventLogQuery(null, PathType.LogName, structuredQuery);
            query.ReverseDirection = false;
            EventLogReader reader = new EventLogReader(query);
            // The Event Log can only return a maximum of 2 MB at a time, but it does not actually limit itself to this when collecting <BatchSize> events.
            // If the number of requested events exceeds 2 MB of event data an exception will be throw (System.Diagnostics.Eventing.Reader.EventLogException: The data area passed to a system call is too small).
            // Since an event is at most 64 KB, 30 events is a conservative limit to ensure the 2 MB limit is never crossed.
            // Setting a smaller batch size does have a small performance impact, but not enough to notice in this scenario.
            reader.BatchSize = 30;

            EventRecord entry;
            while ((entry = reader.ReadEvent()) != null)
            {
                var entryTimeCreated = entry.TimeCreated ?? DateTime.Now;
                var entryMachineName = entry.MachineName;
                var entryLogName = entry.LogName;
                var entryId = entry.Id;
                var entryProviderName = entry.ProviderName;

                string entryLevelDisplayName = "";
                try
                {
                    entryLevelDisplayName = entry.LevelDisplayName;
                }
                catch
                {
                    if (entry.Level != null) entryLevelDisplayName = ((StandardEventLevel) entry.Level).ToString();
                }

                string entryMessage = CleanUpMessage(entry.FormatDescription());
                if (entryMessage == null && entry.Properties.Count > 0)
                {
                    string entryProperties = String.Join(", ", entry.Properties.Select(p => String.Format("'{0}'", p.Value)));
                    entryMessage = String.Format(Coloma.descNotFoundMsgTemplate, entryId, entryProviderName, entryProperties);
                }

                if (entryId == 2 && entry.ProviderId.HasValue && entry.ProviderId.Value == servicingProvider)
                {
                    if (entry.Properties.Count == 5 && entry.Properties[2].Value.ToString() == "Installed")
                    {
                        string kb = entry.Properties[0].Value.ToString();

                        KBRevision KBRev;
                        if(installedUpdates.TryGetValue(kb, out KBRev))
                        {
                            // Update InstallDate with a more precise time
                            KBRev.InstallDate = entryTimeCreated;
                            KBRev.FoundInSetupLog = true;

                            currentKb = KBRev;
                        }
                        else
                        {
                            currentKb = new KBRevision { InstallDate = entryTimeCreated, Kb = kb, FoundInSetupLog = true };
                            installedUpdates.Add(kb, new KBRevision(currentKb));
                        }
                    }
                }
                else if (entryId == 6009 && entry.ProviderName == "EventLog")
                {
                    if (firstBuildEvent.index == 0 && entry.Properties.Count == 5)
                    {
                        uint.TryParse(entry.Properties[1].Value.ToString(), out currentBuild);

                        // If the boot event indicates an earlier build, remember it so we can set all the prior events to this build number
                        if (firstBuildEvent.build != currentBuild)
                        {
                            firstBuildEvent.index = list.Count + 1;
                            firstBuildEvent.build = currentBuild;
                        }
                        // Else the event indicates no build number change, so don't bother checking later boot events either
                        else
                        {
                            firstBuildEvent.index = -1;
                        }
                    }

                    // This event doesn't go into the log file
                    continue;
                }

                list.Add(new ColomaEvent(wvi.branch, currentBuild, currentKb, entryMachineName, DeviceId,
                    Environment.UserName, entryLogName, entryLevelDisplayName, entryId,
                    entryTimeCreated, entryProviderName, entryMessage));
            }

            IEnumerable<KBRevision> orderedUpdates = installedUpdates.Select(kb => kb.Value).OrderBy(kb => kb.InstallDate);
            IEnumerable<KBRevision> missingUpdates = orderedUpdates.Where(kb => !kb.FoundInSetupLog);
            IEnumerator<KBRevision> currentMissingEnum = missingUpdates.GetEnumerator(); currentMissingEnum.MoveNext();
            IEnumerator<KBRevision> nextInstalled = orderedUpdates.GetEnumerator(); nextInstalled.MoveNext();
            DateTime nextInstallTime = DateTime.Now;

            Action getNextInstallTime = new Action(() =>
            {
                if (nextInstalled.Current != null && currentMissingEnum != null && currentMissingEnum.Current != null)
                {
                    do
                    {
                        if (nextInstalled.Current.Kb == currentMissingEnum.Current.Kb)
                        {
                            if (nextInstalled.MoveNext())
                            {
                                nextInstallTime = nextInstalled.Current.InstallDate;

                                // Install times from WMI only include the date, so skip ahead to the next install that falls on a later date or has a more precise time from a setup event
                                while (!nextInstalled.Current.FoundInSetupLog && nextInstallTime >= currentMissingEnum.Current.InstallDate && nextInstallTime < currentMissingEnum.Current.InstallDate.AddDays(1))
                                {
                                    if (nextInstalled.MoveNext())
                                    {
                                        nextInstallTime = nextInstalled.Current.InstallDate;
                                    }
                                    else
                                    {
                                        nextInstallTime = DateTime.Now;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                nextInstallTime = DateTime.Now;
                                break;
                            }

                            break;
                        }
                    }
                    while (nextInstalled.MoveNext());
                }
            });

            getNextInstallTime();

            int fixupsRemaining = (firstBuildEvent.index > 0 ? 1 : 0) + (missingUpdates.Any() ? 1 : 0);

            foreach (var evt in list)
            {
                if (fixupsRemaining == 0)
                {
                    break;
                }

                // If there was a EventLog 6009 event with a different build number, go back and set all the events before it to have that build number
                // This is highly unlikely to ever happen under the current OS-swap upgrade mechanism because the logs get cleared during each upgrade
                if (firstBuildEvent.index > 0)
                {
                    firstBuildEvent.index--;
                    if (firstBuildEvent.index <= 0)
                    {
                        fixupsRemaining--;
                    }
                    else
                    {
                        evt.Build = firstBuildEvent.build;
                    }
                }

                // If there are installed KBs found via WMI that were not in the Setup log, go back and set all the events between the KB installation time
                // and the next KB installation time to use this KB number.
                if (currentMissingEnum != null && currentMissingEnum.Current != null)
                {
                    if (evt.TimeCreated >= currentMissingEnum.Current.InstallDate && evt.TimeCreated < nextInstallTime)
                    {
                        evt.MostRecentKb = new KBRevision(currentMissingEnum.Current);

                        // Since the installations times from WMI are only accurate to the day, append a * to the KB name for any events that fall on that day, to indicate uncertainty.
                        if (evt.TimeCreated >= evt.MostRecentKb.InstallDate && evt.TimeCreated < evt.MostRecentKb.InstallDate.AddDays(1))
                        {
                            evt.MostRecentKb.Kb += "*";
                        }
                    }
                    else if (evt.TimeCreated >= nextInstallTime)
                    {
                        if (currentMissingEnum.MoveNext())
                        {
                            getNextInstallTime();
                        }
                        else
                        {
                            currentMissingEnum = null;
                            fixupsRemaining--;
                        }
                    }
                }
            }
        }