Beispiel #1
0
        public AmcacheNew(string hive, bool recoverDeleted, bool noLogs)
        {
            _logger = LogManager.GetCurrentClassLogger();

            RegistryHive reg;

            var dirname  = Path.GetDirectoryName(hive);
            var hiveBase = Path.GetFileName(hive);

            List <RawCopyReturn> rawFiles = null;

            try
            {
                reg = new RegistryHive(hive)
                {
                    RecoverDeleted = true
                };
            }
            catch (IOException)
            {
                //file is in use

                if (RawCopy.Helper.IsAdministrator() == false)
                {
                    throw new UnauthorizedAccessException("Administrator privileges not found!");
                }

                _logger.Warn($"'{hive}' is in use. Rerouting...\r\n");

                var files = new List <string>();
                files.Add(hive);

                var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?");

                foreach (var logFile in logFiles)
                {
                    files.Add(logFile);
                }

                rawFiles = RawCopy.Helper.GetFiles(files);

                var b = new byte[rawFiles.First().FileStream.Length];

                rawFiles.First().FileStream.Read(b, 0, (int)rawFiles.First().FileStream.Length);

                reg = new RegistryHive(b, rawFiles.First().InputFilename);
            }

            if (reg.Header.PrimarySequenceNumber != reg.Header.SecondarySequenceNumber)
            {
                if (string.IsNullOrEmpty(dirname))
                {
                    dirname = ".";
                }

                var logFiles = Directory.GetFiles(dirname, $"{hiveBase}.LOG?");
                var log      = LogManager.GetCurrentClassLogger();

                if (logFiles.Length == 0)
                {
                    if (noLogs == false)
                    {
                        log.Warn(
                            "Registry hive is dirty and no transaction logs were found in the same directory! LOGs should have same base name as the hive. Aborting!!");
                        throw new Exception(
                                  "Sequence numbers do not match and transaction logs were not found in the same directory as the hive. Aborting");
                    }

                    log.Warn(
                        "Registry hive is dirty and no transaction logs were found in the same directory. Data may be missing! Continuing anyways...");
                }
                else
                {
                    if (noLogs == false)
                    {
                        if (rawFiles != null)
                        {
                            var lt = new List <TransactionLogFileInfo>();
                            foreach (var rawCopyReturn in rawFiles.Skip(1).ToList())
                            {
                                var b = new byte[rawCopyReturn.FileStream.Length];

                                rawCopyReturn.FileStream.Read(b, 0, (int)rawCopyReturn.FileStream.Length);

                                var tt = new TransactionLogFileInfo(rawCopyReturn.InputFilename, b);
                                lt.Add(tt);
                            }

                            reg.ProcessTransactionLogs(lt, true);
                        }
                        else
                        {
                            reg.ProcessTransactionLogs(logFiles.ToList(), true);
                        }
                    }
                    else
                    {
                        log.Warn(
                            "Registry hive is dirty and transaction logs were found in the same directory, but --nl was provided. Data may be missing! Continuing anyways...");
                    }
                }
            }


            reg.ParseHive();

            var fileKey     = reg.GetKey(@"Root\InventoryApplicationFile");
            var programsKey = reg.GetKey(@"Root\InventoryApplication");


            UnassociatedFileEntries = new List <FileEntryNew>();
            ProgramsEntries         = new List <ProgramsEntryNew>();
            DeviceContainers        = new List <DeviceContainer>();
            DevicePnps     = new List <DevicePnp>();
            DriveBinaries  = new List <DriverBinary>();
            DriverPackages = new List <DriverPackage>();
            ShortCuts      = new List <Shortcut>();

            _logger.Debug("Getting Programs data");


            if (programsKey != null)
            {
                foreach (var registryKey in programsKey.SubKeys)
                {
                    var            bundleManifestPath = string.Empty;
                    var            hiddenArp          = false;
                    var            inboxModernApp     = false;
                    DateTimeOffset?installDate        = null;
                    var            language           = 0;
                    var            manifestPath       = string.Empty;
                    var            msiPackageCode     = string.Empty;
                    var            msiProductCode     = string.Empty;
                    var            name = string.Empty;
                    var            osVersionAtInstallTime = string.Empty;
                    var            packageFullName        = string.Empty;
                    var            programId         = string.Empty;
                    var            programInstanceId = string.Empty;
                    var            publisher         = string.Empty;
                    var            registryKeyPath   = string.Empty;
                    var            rootDirPath       = string.Empty;
                    var            source            = string.Empty;
                    var            storeAppType      = string.Empty;
                    var            type                       = string.Empty;
                    var            uninstallString            = string.Empty;
                    var            version                    = string.Empty;
                    var            installDateArpLastModified = string.Empty;
                    DateTimeOffset?installDateMsi             = null;
                    var            installDateFromLinkFile    = string.Empty;
                    var            manufacturer               = string.Empty;
                    var            driverVerVersion           = string.Empty;


                    try
                    {
                        foreach (var registryKeyValue in registryKey.Values)
                        {
                            switch (registryKeyValue.ValueName)
                            {
                            case "BundleManifestPath":
                                bundleManifestPath = registryKeyValue.ValueData;
                                break;

                            case "HiddenArp":
                                hiddenArp = registryKeyValue.ValueData == "1";
                                break;

                            case "InboxModernApp":
                                inboxModernApp = registryKeyValue.ValueData == "1";
                                break;

                            case "InstallDate":
                                if (registryKeyValue.ValueData.Length > 0)
                                {
                                    // _logger.Warn($"registryKeyValue.ValueData for InstallDate as InvariantCulture: {registryKeyValue.ValueData.ToString(CultureInfo.InvariantCulture)}");
                                    var d = new DateTimeOffset(
                                        DateTime.Parse(registryKeyValue.ValueData, DateTimeFormatInfo.InvariantInfo)
                                        .Ticks,
                                        TimeSpan.Zero);
                                    installDate = d;
                                }

                                break;

                            case "Language":
                                if (registryKeyValue.ValueData.Length == 0)
                                {
                                    language = 0;
                                }
                                else
                                {
                                    language = int.Parse(registryKeyValue.ValueData);
                                }

                                break;

                            case "ManifestPath":
                                manifestPath = registryKeyValue.ValueData;
                                break;

                            case "MsiPackageCode":
                                msiPackageCode = registryKeyValue.ValueData;
                                break;

                            case "MsiProductCode":
                                msiProductCode = registryKeyValue.ValueData;
                                break;

                            case "Name":
                                name = registryKeyValue.ValueData;
                                break;

                            case "OSVersionAtInstallTime":
                                osVersionAtInstallTime = registryKeyValue.ValueData;
                                break;

                            case "PackageFullName":
                                packageFullName = registryKeyValue.ValueData;
                                break;

                            case "ProgramId":
                                programId = registryKeyValue.ValueData;
                                break;

                            case "ProgramInstanceId":
                                programInstanceId = registryKeyValue.ValueData;
                                break;

                            case "Publisher":
                                publisher = registryKeyValue.ValueData;
                                break;

                            case "RegistryKeyPath":
                                registryKeyPath = registryKeyValue.ValueData;
                                break;

                            case "RootDirPath":
                                rootDirPath = registryKeyValue.ValueData;
                                break;

                            case "Source":
                                source = registryKeyValue.ValueData;
                                break;

                            case "StoreAppType":
                                storeAppType = registryKeyValue.ValueData;
                                break;

                            case "Type":
                                type = registryKeyValue.ValueData;
                                break;

                            case "UninstallString":
                                uninstallString = registryKeyValue.ValueData;
                                break;

                            case "Version":
                                version = registryKeyValue.ValueData;
                                break;

                            case "InstallDateArpLastModified":
                                if (registryKeyValue.ValueData.Length > 0)
                                {
                                    installDateArpLastModified = registryKeyValue.ValueData;
                                }

                                break;

                            case "InstallDateMsi":
                                if (registryKeyValue.ValueData.Length > 0)
                                {
                                    // _logger.Warn($"registryKeyValue.ValueData for InstallDate as InvariantCulture: {registryKeyValue.ValueData.ToString(CultureInfo.InvariantCulture)}");
                                    var d = new DateTimeOffset(
                                        DateTime.Parse(registryKeyValue.ValueData, DateTimeFormatInfo.InvariantInfo)
                                        .Ticks,
                                        TimeSpan.Zero);
                                    installDateMsi = d;
                                }

                                break;

                            case "InstallDateFromLinkFile":
                                if (registryKeyValue.ValueData.Length > 0)
                                {
                                    installDateFromLinkFile = registryKeyValue.ValueData;
                                }

                                break;

                            case "DriverVerVersion":
                            case "BusReportedDescription":
                            case "HWID":
                            case "COMPID":
                            case "STACKID":
                            case "UpperClassFilters":
                            case "UpperFilters":
                            case "LowerFilters":
                            case "BinFileVersion":
                            case "(default)":


                                break;

                            case "Manufacturer":
                                if (registryKeyValue.ValueData.Length > 0)
                                {
                                    manufacturer = registryKeyValue.ValueData;
                                }

                                break;

                            default:
                                _logger.Warn(
                                    $"Unknown value name in InventoryApplication at path {registryKey.KeyPath}: {registryKeyValue.ValueName}");
                                break;
                            }
                        }

                        var pe = new ProgramsEntryNew(bundleManifestPath, hiddenArp, inboxModernApp, installDate,
                                                      language,
                                                      manifestPath, msiPackageCode, msiProductCode, name, osVersionAtInstallTime, packageFullName,
                                                      programId, programInstanceId, publisher, registryKeyPath, rootDirPath, source, storeAppType,
                                                      type, uninstallString, version, registryKey.LastWriteTime.Value, installDateArpLastModified,
                                                      installDateMsi, installDateFromLinkFile, manufacturer);

                        ProgramsEntries.Add(pe);
                    }
                    catch (Exception ex)
                    {
                        if (registryKey.NkRecord.IsFree == false)
                        {
                            _logger.Error($"Error parsing ProgramsEntry at {registryKey.KeyPath}. Error: {ex.Message}");
                            _logger.Error(
                                $"Please send the following text to [email protected]. \r\n\r\nKey data: {registryKey}");
                        }
                    }
                }
            }
            else
            {
                _logger.Warn("Hive does not contain a Root\\InventoryApplication key.");
            }

            _logger.Debug("Getting Files data");


            if (fileKey != null)
            {
                foreach (var subKey in fileKey.SubKeys)
                {
                    var            binaryType        = string.Empty;
                    var            binFileVersion    = string.Empty;
                    var            binProductVersion = string.Empty;
                    var            fileId            = string.Empty;
                    var            isOsComponent     = false;
                    var            isPeFile          = false;
                    var            language          = 0;
                    DateTimeOffset?linkDate          = null;
                    var            longPathHash      = string.Empty;
                    var            lowerCaseLongPath = string.Empty;
                    var            name           = string.Empty;
                    var            productName    = string.Empty;
                    var            productVersion = string.Empty;
                    var            programId      = string.Empty;
                    var            publisher      = string.Empty;
                    long           size           = 0;
                    ulong          usn            = 0;
                    var            version        = string.Empty;
                    var            description    = string.Empty;

                    var hasLinkedProgram = false;

                    try
                    {
                        foreach (var subKeyValue in subKey.Values)
                        {
                            switch (subKeyValue.ValueName)
                            {
                            case "BinaryType":
                                binaryType = subKeyValue.ValueData;
                                break;

                            case "BinFileVersion":
                                binFileVersion = subKeyValue.ValueData;
                                break;

                            case "BinProductVersion":
                                binProductVersion = subKeyValue.ValueData;
                                break;

                            case "FileId":
                                fileId = subKeyValue.ValueData;
                                break;

                            case "IsOsComponent":
                                isOsComponent = subKeyValue.ValueData == "1";
                                break;

                            case "IsPeFile":
                                isPeFile = subKeyValue.ValueData == "1";
                                break;

                            case "Language":
                                language = int.Parse(subKeyValue.ValueData);
                                break;

                            case "LinkDate":
                                if (subKeyValue.ValueData.Length > 0)
                                {
                                    var d = new DateTimeOffset(
                                        DateTime.Parse(subKeyValue.ValueData, DateTimeFormatInfo.InvariantInfo)
                                        .Ticks,
                                        TimeSpan.Zero);
                                    linkDate = d;
                                }

                                break;

                            case "LongPathHash":
                                longPathHash = subKeyValue.ValueData;
                                break;

                            case "LowerCaseLongPath":
                                lowerCaseLongPath = subKeyValue.ValueData;
                                break;

                            case "Name":
                                name = subKeyValue.ValueData;
                                break;

                            case "ProductName":
                                productName = subKeyValue.ValueData;
                                break;

                            case "ProductVersion":
                                productVersion = subKeyValue.ValueData;
                                break;

                            case "ProgramId":
                                programId = subKeyValue.ValueData;

                                var program = ProgramsEntries.SingleOrDefault(t => t.ProgramId == programId);
                                if (program != null)
                                {
                                    hasLinkedProgram = true;
                                }

                                break;

                            case "Publisher":
                                publisher = subKeyValue.ValueData;
                                break;

                            case "Size":
                                try
                                {
                                    if (subKeyValue.ValueData.StartsWith("0x"))
                                    {
                                        size = long.Parse(subKeyValue.ValueData.Replace("0x", ""),
                                                          NumberStyles.HexNumber);
                                    }
                                    else
                                    {
                                        size = long.Parse(subKeyValue.ValueData);
                                    }
                                }
                                catch (Exception e)
                                {
                                }

                                break;

                            case "BusReportedDescription":
                            case "FileSize":
                            case "Model":
                            case "Manufacturer":
                            case "ParentId":
                            case "MatchingID":
                            case "ClassGuid":
                            case "DriverName":
                            case "Enumerator":
                            case "Service":
                            case "DeviceState":
                            case "InstallState":
                            case "DriverVerVersion":
                            case "DriverPackageStrongName":
                            case "DriverVerDate":
                            case "AppxPackageRelativeId":
                            case "AppxPackageFullName":
                            case "ContainerId":
                            case "HiddenArp":
                            case "Inf":
                            case "ProblemCode":

                            case "Provider":
                            case "Class":
                                break;

                            case "Description":
                                description = subKeyValue.ValueData;
                                break;

                            case "Version":
                                version = subKeyValue.ValueData;
                                break;

                            case "Usn":
                                usn = ulong.Parse(subKeyValue.ValueData);
                                break;

                            default:
                                if (subKeyValue.VkRecord.IsFree == false)
                                {
                                    _logger.Warn(
                                        $"Unknown value name when processing FileEntry at path '{subKey.KeyPath}': {subKeyValue.ValueName}");
                                }

                                break;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (subKey.NkRecord.IsFree == false)
                        {
                            _logger.Error($"Error parsing FileEntry at {subKey.KeyPath}. Error: {ex.Message}");
                            _logger.Error(
                                $"Please send the following text to [email protected]. \r\n\r\nKey data: {subKey}");
                        }
                    }

                    TotalFileEntries += 1;


                    var fe = new FileEntryNew(binaryType, binFileVersion, productVersion, fileId, isOsComponent,
                                              isPeFile,
                                              language, linkDate, longPathHash, lowerCaseLongPath, name, productName, productVersion,
                                              programId,
                                              publisher, size, version, subKey.LastWriteTime.Value, binProductVersion, usn, description);

                    if (hasLinkedProgram)
                    {
                        var program = ProgramsEntries.SingleOrDefault(t => t.ProgramId == fe.ProgramId);
                        if (program != null)
                        {
                            fe.ApplicationName = program.Name;
                            program.FileEntries.Add(fe);
                        }
                    }
                    else
                    {
                        fe.ApplicationName = "Unassociated";
                        UnassociatedFileEntries.Add(fe);
                    }
                }
            }
            else
            {
                _logger.Warn("Hive does not contain a Root\\InventoryApplicationFile key.");
            }

            _logger.Debug("Getting Shortcut data");

            var shortCutkey = reg.GetKey(@"Root\InventoryApplicationShortcut");

            if (shortCutkey != null)
            {
                foreach (var shortCutkeySubKey in shortCutkey.SubKeys)
                {
                    var lnkName = "";
                    if (shortCutkeySubKey.Values.Count > 0)
                    {
                        lnkName = shortCutkeySubKey.Values.First().ValueData;
                    }
                    ShortCuts.Add(new Shortcut(shortCutkeySubKey.KeyName, lnkName,
                                               shortCutkeySubKey.LastWriteTime.Value));
                }
            }

            _logger.Debug("Getting InventoryDeviceContainer data");


            var deviceKey = reg.GetKey(@"Root\InventoryDeviceContainer");

            if (deviceKey != null)
            {
                foreach (var deviceSubKey in deviceKey.SubKeys)
                {
                    var categories         = string.Empty;
                    var discoveryMethod    = string.Empty;
                    var friendlyName       = string.Empty;
                    var icon               = string.Empty;
                    var isActive           = false;
                    var isConnected        = false;
                    var isMachineContainer = false;
                    var isNetworked        = false;
                    var isPaired           = false;
                    var manufacturer       = string.Empty;
                    var modelId            = string.Empty;
                    var modelName          = string.Empty;
                    var modelNumber        = string.Empty;
                    var primaryCategory    = string.Empty;
                    var state              = string.Empty;

                    try
                    {
                        foreach (var keyValue in deviceSubKey.Values)
                        {
                            switch (keyValue.ValueName)
                            {
                            case "Categories":
                                categories = keyValue.ValueData;
                                break;

                            case "DiscoveryMethod":
                                discoveryMethod = keyValue.ValueData;
                                break;

                            case "FriendlyName":
                                friendlyName = keyValue.ValueData;
                                break;

                            case "Icon":
                                icon = keyValue.ValueData;
                                break;

                            case "IsActive":
                                isActive = keyValue.ValueData == "1";
                                break;

                            case "IsConnected":
                                isConnected = keyValue.ValueData == "1";
                                break;

                            case "IsMachineContainer":
                                isMachineContainer = keyValue.ValueData == "1";
                                break;

                            case "IsNetworked":
                                isNetworked = keyValue.ValueData == "1";
                                break;

                            case "IsPaired":
                                isPaired = keyValue.ValueData == "1";
                                break;

                            case "Manufacturer":
                                manufacturer = keyValue.ValueData;
                                break;

                            case "ModelId":
                                modelId = keyValue.ValueData;
                                break;

                            case "ModelName":
                                modelName = keyValue.ValueData;
                                break;

                            case "ModelNumber":
                                modelNumber = keyValue.ValueData;
                                break;

                            case "PrimaryCategory":
                                primaryCategory = keyValue.ValueData;
                                break;

                            case "State":
                                state = keyValue.ValueData;
                                break;

                            case "(default)":
                            case "Model":
                            case "BusReportedDescription":
                            case "Version":
                            case "LowerClassFilters":
                            case "ManifestPath":
                            case "UpperClassFilters":
                                break;

                            default:
                                _logger.Warn(
                                    $"Unknown value name when processing DeviceContainer at path '{deviceSubKey.KeyPath}': {keyValue.ValueName}");
                                break;
                            }
                        }

                        var dc = new DeviceContainer(deviceSubKey.KeyName, deviceSubKey.LastWriteTime.Value, categories,
                                                     discoveryMethod, friendlyName, icon, isActive, isConnected, isMachineContainer, isNetworked,
                                                     isPaired, manufacturer, modelId, modelName, modelNumber, primaryCategory, state);

                        DeviceContainers.Add(dc);
                    }
                    catch (Exception ex)
                    {
                        if (deviceSubKey.NkRecord.IsFree == false)
                        {
                            _logger.Error(
                                $"Error parsing DeviceContainer at {deviceSubKey.KeyPath}. Error: {ex.Message}");
                            _logger.Error(
                                $"Please send the following text to [email protected]. \r\n\r\nKey data: {deviceSubKey}");
                        }
                    }
                }
            }

            _logger.Debug("Getting InventoryDevicePnp data");

            var pnpKey = reg.GetKey(@"Root\InventoryDevicePnp");

            if (pnpKey != null)
            {
                foreach (var pnpsKey in pnpKey.SubKeys)
                {
                    var busReportedDescription = string.Empty;
                    var Class                   = string.Empty;
                    var classGuid               = string.Empty;
                    var compid                  = string.Empty;
                    var containerId             = string.Empty;
                    var description             = string.Empty;
                    var deviceState             = string.Empty;
                    var driverId                = string.Empty;
                    var driverName              = string.Empty;
                    var driverPackageStrongName = string.Empty;
                    var driverVerDate           = string.Empty;
                    var driverVerVersion        = string.Empty;
                    var enumerator              = string.Empty;
                    var hwid         = string.Empty;
                    var inf          = string.Empty;
                    var installState = string.Empty;
                    var manufacturer = string.Empty;
                    var matchingId   = string.Empty;
                    var model        = string.Empty;
                    var parentId     = string.Empty;
                    var problemCode  = string.Empty;
                    var provider     = string.Empty;
                    var service      = string.Empty;
                    var stackid      = string.Empty;

                    try
                    {
                        foreach (var keyValue in pnpsKey.Values)
                        {
                            switch (keyValue.ValueName)
                            {
                            case "BusReportedDescription":
                                busReportedDescription = keyValue.ValueData;
                                break;

                            case "Class":
                                Class = keyValue.ValueData;
                                break;

                            case "ClassGuid":
                                classGuid = keyValue.ValueData;
                                break;

                            case "COMPID":
                                compid = keyValue.ValueData;
                                break;

                            case "ContainerId":
                                containerId = keyValue.ValueData;
                                break;

                            case "Description":
                                description = keyValue.ValueData;
                                break;

                            case "DeviceState":
                                deviceState = keyValue.ValueData;
                                break;

                            case "DriverId":
                                driverId = keyValue.ValueData;
                                break;

                            case "DriverName":
                                driverName = keyValue.ValueData;
                                break;

                            case "DriverPackageStrongName":
                                driverPackageStrongName = keyValue.ValueData;
                                break;

                            case "DriverVerDate":
                                driverVerDate = keyValue.ValueData;
                                break;

                            case "DriverVerVersion":
                                driverVerVersion = keyValue.ValueData;
                                break;

                            case "Enumerator":
                                enumerator = keyValue.ValueData;
                                break;

                            case "HWID":
                                hwid = keyValue.ValueData;
                                break;

                            case "Inf":
                                inf = keyValue.ValueData;
                                break;

                            case "InstallState":
                                installState = keyValue.ValueData;
                                break;

                            case "LowerClassFilters":
                            case "LowerFilters":
                                break;

                            case "Manufacturer":
                                manufacturer = keyValue.ValueData;
                                break;

                            case "MatchingID":
                                matchingId = keyValue.ValueData;
                                break;

                            case "Model":
                                model = keyValue.ValueData;
                                break;

                            case "ParentId":
                                parentId = keyValue.ValueData;
                                break;

                            case "ProblemCode":
                                problemCode = keyValue.ValueData;
                                break;

                            case "Provider":
                                provider = keyValue.ValueData;
                                break;

                            case "Service":
                                service = keyValue.ValueData;
                                break;

                            case "STACKID":
                                stackid = keyValue.ValueData;
                                break;

                            case "UpperClassFilters":
                            case "UpperFilters":
                            case "ExtendedInfs":
                            case "DeviceInterfaceClasses":
                            case "(default)":
                            case "DeviceExtDriversFlightIds":
                            case "InstallDate":
                            case "FirstInstallDate":
                            case "DeviceDriverFlightId":
                                _logger.Debug($"Value: '{keyValue.ValueName}' --> {keyValue.ValueData}");
                                break;

                            default:
                                _logger.Warn(
                                    $"Unknown value name when processing DevicePnp at path '{pnpsKey.KeyPath}': {keyValue.ValueName}");
                                break;
                            }
                        }

                        var dp = new DevicePnp(pnpsKey.KeyName, pnpsKey.LastWriteTime.Value, busReportedDescription,
                                               Class, classGuid, compid, containerId, description, deviceState, driverId, driverName,
                                               driverPackageStrongName, driverVerDate, driverVerVersion, enumerator, hwid, inf,
                                               installState, manufacturer, matchingId, model, parentId, problemCode, provider, service,
                                               stackid);

                        DevicePnps.Add(dp);
                    }
                    catch (Exception ex)
                    {
                        if (pnpKey.NkRecord.IsFree == false)
                        {
                            _logger.Error($"Error parsing DevicePnp at {pnpKey.KeyPath}. Error: {ex.Message}");
                            _logger.Error(
                                $"Please send the following text to [email protected]. \r\n\r\nKey data: {pnpKey}");
                        }
                    }
                }
            }

            _logger.Debug("Getting InventoryDriverBinary data");

            var binaryKey = reg.GetKey(@"Root\InventoryDriverBinary");

            if (binaryKey != null)
            {
                foreach (var binKey in binaryKey.SubKeys)
                {
                    var            driverCheckSum          = 0;
                    var            driverCompany           = string.Empty;
                    var            driverId                = string.Empty;
                    var            driverInBox             = false;
                    var            driverIsKernelMode      = false;
                    DateTimeOffset?driverLastWriteTime     = null;
                    var            driverName              = string.Empty;
                    var            driverPackageStrongName = string.Empty;
                    var            driverSigned            = false;
                    DateTimeOffset?driverTimeStamp         = null;
                    var            driverType              = string.Empty;
                    var            driverVersion           = string.Empty;
                    var            imageSize               = 0;
                    var            inf            = string.Empty;
                    var            product        = string.Empty;
                    var            productVersion = string.Empty;
                    var            service        = string.Empty;
                    var            wdfVersion     = string.Empty;


                    try
                    {
                        foreach (var keyValue in binKey.Values)
                        {
                            switch (keyValue.ValueName)
                            {
                            case "DriverCheckSum":
                                driverCheckSum = int.Parse(keyValue.ValueData);
                                break;

                            case "DriverCompany":
                                driverCompany = keyValue.ValueData;
                                break;

                            case "DriverId":
                                driverId = keyValue.ValueData;
                                break;

                            case "DriverInBox":
                                driverInBox = keyValue.ValueData == "1";
                                break;

                            case "DriverIsKernelMode":
                                driverIsKernelMode = keyValue.ValueData == "1";
                                break;

                            case "DriverLastWriteTime":
                                if (keyValue.ValueData.Length > 0)
                                {
                                    var d = new DateTimeOffset(
                                        DateTime.Parse(keyValue.ValueData, DateTimeFormatInfo.InvariantInfo).Ticks,
                                        TimeSpan.Zero);
                                    driverLastWriteTime = d;
                                }

                                break;

                            case "DriverName":
                                driverName = keyValue.ValueData;
                                break;

                            case "DriverPackageStrongName":
                                driverPackageStrongName = keyValue.ValueData;
                                break;

                            case "DriverSigned":
                                driverSigned = keyValue.ValueData == "1";
                                break;

                            case "DriverTimeStamp":
                                //DateTimeOffset.FromUnixTimeSeconds(seca).ToUniversalTime();
                                var seca = long.Parse(keyValue.ValueData);
                                if (seca > 0)
                                {
                                    driverTimeStamp = DateTimeOffset.FromUnixTimeSeconds(seca).ToUniversalTime();
                                }

                                break;

                            case "DriverType":
                                driverType = keyValue.ValueData;
                                break;

                            case "DriverVersion":
                                driverVersion = keyValue.ValueData;
                                break;

                            case "ImageSize":
                                imageSize = int.Parse(keyValue.ValueData);
                                break;

                            case "Inf":
                                inf = keyValue.ValueData;
                                break;

                            case "Product":
                                product = keyValue.ValueData;
                                break;

                            case "ProductVersion":
                                productVersion = keyValue.ValueData;
                                break;

                            case "Service":
                                service = keyValue.ValueData;
                                break;

                            case "WdfVersion":
                                wdfVersion = keyValue.ValueData;
                                break;

                            case "(default)":
                            case "COMPID":
                            case "HWID":
                                break;

                            default:
                                _logger.Warn(
                                    $"Unknown value name when processing DriverBinary at path '{binKey.KeyPath}': {keyValue.ValueName}");
                                break;
                            }
                        }

                        var db = new DriverBinary(binKey.KeyName, binKey.LastWriteTime.Value, driverCheckSum,
                                                  driverCompany, driverId, driverInBox, driverIsKernelMode, driverLastWriteTime, driverName,
                                                  driverPackageStrongName, driverSigned, driverTimeStamp, driverType, driverVersion,
                                                  imageSize, inf, product, productVersion, service, wdfVersion);

                        DriveBinaries.Add(db);
                    }
                    catch (Exception ex)
                    {
                        if (binaryKey.NkRecord.IsFree == false)
                        {
                            _logger.Error($"Error parsing DriverBinary at {binaryKey.KeyPath}. Error: {ex.Message}");
                            _logger.Error(
                                $"Please send the following text to [email protected]. \r\n\r\nKey data: {binaryKey}");
                        }
                    }
                }
            }

            _logger.Debug("Getting InventoryDriverPackage data");

            var packaheKey = reg.GetKey(@"Root\InventoryDriverPackage");

            if (packaheKey != null)
            {
                foreach (var packKey in packaheKey.SubKeys)
                {
                    var            Class        = string.Empty;
                    var            ClassGuid    = string.Empty;
                    DateTimeOffset?Date         = null;
                    var            Directory    = string.Empty;
                    var            DriverInBox  = false;
                    var            Hwids        = string.Empty;
                    var            Inf          = string.Empty;
                    var            Provider     = string.Empty;
                    var            SubmissionId = string.Empty;
                    var            SYSFILE      = string.Empty;
                    var            Version      = string.Empty;


                    try
                    {
                        foreach (var keyValue in packKey.Values)
                        {
                            switch (keyValue.ValueName)
                            {
                            case "Class":
                                Class = keyValue.ValueData;
                                break;

                            case "ClassGuid":
                                ClassGuid = keyValue.ValueData;
                                break;

                            case "Date":
                                if (keyValue.ValueData.Length > 0)
                                {
                                    var d = new DateTimeOffset(
                                        DateTime.Parse(keyValue.ValueData, DateTimeFormatInfo.InvariantInfo).Ticks,
                                        TimeSpan.Zero);
                                    Date = d;
                                }

                                break;

                            case "Directory":
                                Directory = keyValue.ValueData;
                                break;

                            case "DriverInBox":
                                DriverInBox = keyValue.ValueData == "1";
                                break;

                            case "Hwids":
                                Hwids = keyValue.ValueData;
                                break;

                            case "Inf":
                                Inf = keyValue.ValueData;
                                break;

                            case "Provider":
                                Provider = keyValue.ValueData;
                                break;

                            case "SubmissionId":
                                SubmissionId = keyValue.ValueData;
                                break;

                            case "SYSFILE":
                                SYSFILE = keyValue.ValueData;
                                break;

                            case "Version":
                                Version = keyValue.ValueData;
                                break;

                            case "IsActive":

                                break;

                            default:
                                _logger.Warn(
                                    $"Unknown value name when processing DriverPackage at path '{packKey.KeyPath}': {keyValue.ValueName}");
                                break;
                            }
                        }

                        var dp = new DriverPackage(packKey.KeyName, packKey.LastWriteTime.Value, Class, ClassGuid,
                                                   Date, Directory, DriverInBox, Hwids, Inf, Provider, SubmissionId, SYSFILE, Version);

                        DriverPackages.Add(dp);
                    }
                    catch (Exception ex)
                    {
                        if (packaheKey.NkRecord.IsFree == false)
                        {
                            _logger.Error($"Error parsing DriverPackage at {packaheKey.KeyPath}. Error: {ex.Message}");
                            _logger.Error(
                                $"Please send the following text to [email protected]. \r\n\r\nKey data: {packaheKey}");
                        }
                    }
                }
            }
        }
Beispiel #2
0
        void InstallThreadHandler()
        {
            try
            {
                Trace.WriteLine("Thread");
                Assembly curAssm;
                curAssm = Assembly.GetAssembly(this.GetType());
                int  registertimeout = 0;
                bool wmiregistered   = false;
                while (registertimeout < 30 * 1000)
                {
                    Trace.WriteLine("Try to register WMI");
                    try
                    {
                        if (System.Management.Instrumentation.Instrumentation.IsAssemblyRegistered(curAssm))
                        {
                            //Cool; it's already registered in WMI
                            Trace.WriteLine("Already registered");
                            wmiregistered = true;
                            break;
                        }
                        else //Well then, register it
                        {
                            Trace.WriteLine("Ensure we are registered with WMI");

                            System.Management.Instrumentation.Instrumentation.RegisterAssembly(curAssm);
                            wmiregistered = true;
                            break;
                        }
                    }
                    catch (ManagementException)
                    {
                        Trace.WriteLine("Waiting for WMI to initialise");
                        Thread.Sleep(500);
                        registertimeout += 500;
                    }
                    catch (Exception e)
                    {
                        Trace.WriteLine("WMI initialisation not finished (" + e.ToString() + ")");
                        Thread.Sleep(500);
                        registertimeout += 500;
                    }
                }
                if (!wmiregistered)
                {
                    Trace.WriteLine("Unable to contact WMI");
                    InstallState.Fail("Unable to contact WMI");
                }
                Trace.WriteLine("Got WMI connection");
                CitrixXenServerInstallStatus installstatusclass = new CitrixXenServerInstallStatus(InstallState);
                Trace.WriteLine("got status");
                try
                {
                    Instrumentation.Publish(installstatusclass);
                }
                catch (Exception e)
                {
                    Trace.WriteLine(e.ToString());
                    throw;
                }
                Trace.WriteLine("Begin");
                while (InstallState.PauseOnStart)
                {
                    Trace.WriteLine("Paused");
                    Thread.Sleep(1000);
                    try
                    {
                        int pausestate = (int)Application.CommonAppDataRegistry.GetValue("Continue", 0);
                        if (pausestate != 0)
                        {
                            break;
                        }
                    }
                    catch { };
                }
                ;
                InstallState.MaxProgress = 100;
                InstallState.Progress    = 1;
                Trace.WriteLine("Initializing Install =======================================");


                HwidState     HWID = new HwidState(@"PCI\VEN_5853&DEV_0002&REV_02");
                DriverPackage DriversMsi;
                MsiInstaller  VssProvMsi;
                MsiInstaller  AgentMsi;
                string        installdir;
                NSISItem      InstallerNSIS;
                if (is64BitOS())
                {
                    Trace.WriteLine("64 Bit Install");
                    installdir = (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Citrix\\XenToolsInstaller", "Install_Dir", Application.StartupPath);
                    DriversMsi = new DriverPackage((string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath), Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath) + "citrixxendriversx64.msi");
                    VssProvMsi = new MsiInstaller(Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath) + "citrixvssx64.msi");
                    AgentMsi   = new MsiInstaller(Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath) + "citrixguestagentx64.msi");

                    InstallerNSIS = new NSISItem("Citrix XenTools", (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath));
                }
                else
                {
                    Trace.WriteLine("32 Bit Install");
                    installdir = (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "Install_Dir", Application.StartupPath);
                    DriversMsi = new DriverPackage((string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath), Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath) + "citrixxendriversx86.msi");
                    VssProvMsi = new MsiInstaller(Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath) + "citrixvssx86.msi");
                    AgentMsi   = new MsiInstaller(Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath) + "citrixguestagentx86.msi");

                    InstallerNSIS = new NSISItem("Citrix XenTools", (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath));
                }
                installdir = "\"" + installdir + "\"";

                VifConfig Vif = new VifConfig();
                Trace.WriteLine("Entering state loop");
                Dictionary <string, int[]> prog = new Dictionary <string, int[]>();

                prog["installscore"]     = new int[] { 300, 0 };
                prog["tempscore"]        = new int[] { 0, 0 };
                InstallState.MaxProgress = prog["installscore"][0];

                if (InstallService.isWOW64())
                {
                    Trace.WriteLine("Install failed");
                    InstallState.Fail("PV Tools cannot be installed on systems where .Net applications are forced to run under WoW64\n\nSet HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NetFramework\\Enable64Bit to 1 and attempt the install again.");
                }

                while ((!InstallState.Failed) && (InstallState.RebootCount > 0) && (!InstallState.Done))
                {
                    InstallState.Unchanged  = true;
                    prog["installscore"][1] = 0;
                    if (InstallState.GotAgent)
                    {
                        prog["installscore"][1] += 100;
                    }
                    if (InstallState.NsisFree)
                    {
                        prog["installscore"][1] += 100;
                    }
                    if (InstallState.GotDrivers)
                    {
                        prog["installscore"][1] += 100;
                    }
                    InstallState.MaxProgress = prog["installscore"][0] + prog["tempscore"][0];
                    InstallState.Progress    = prog["installscore"][1] + prog["tempscore"][1];

                    if (InstallState.GotAgent &&
                        ((InstallWizard.InstallerState.WinVersion.isServerSKU() && InstallState.GotVssProvider) || !InstallWizard.InstallerState.WinVersion.isServerSKU()) &&
                        InstallState.GotDrivers &&
                        !InstallState.RebootNow &&
                        InstallState.NsisFree &&
                        !InstallState.NeedsReboot)
                    {
                        Trace.WriteLine("Everything is installed");
                        InstallState.Installed = true;
                        InstallState.Done      = true;

                        /* try
                         * {
                         *  // Registry.LocalMachine.OpenSubKey(@"Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("Run",true).DeleteValue("CitrixXenAgentInstaller");
                         * }
                         * catch (Exception e){
                         *   Trace.WriteLine("Failed to remove install agent run subkey: " + e.ToString());
                         *   InstallState.Fail("Failed to remove install agent run subkey: " + e.ToString());
                         *   continue;
                         * }*/
                        continue;
                    }



                    if ((!InstallState.GotDrivers) && (InstallState.NsisFree) && (!HWID.needsupdate()))
                    {
                        Trace.WriteLine("Check if drivers are functioning");

                        string oldtext = InstallState.DriverText;

                        if ((DriversMsi.installed() && (!DriversMsi.olderinstalled())) && DriversMsi.functioning(ref InstallState.DriverText))
                        {
                            Trace.WriteLine("Drivers functioning");
                            InstallState.GotDrivers = true;
                        }
                        else
                        {
                            if (InstallState.DriverText != oldtext)
                            {
                                InstallState.PollingReset();
                            }
                            if ((!InstallState.DriversPlaced) && ((!DriversMsi.installed()) || DriversMsi.olderinstalled()))
                            {
                                Trace.WriteLine("Driver install package not found");
                                Trace.WriteLine("Attempt driver install");
                                Trace.WriteLine(DriversMsi.ToString());

                                if (DriversMsi.olderinstalled())
                                {
                                    Vif.CopyNewPVWorkaround();
                                }

                                try
                                {
                                    DriversMsi.install("INSTALLDIR=" + installdir, "driversmsi", InstallState);
                                    InstallState.DriversPlaced = true;
                                    InstallState.NeedsReboot   = true;
                                    InstallState.Polling       = true;
                                    Trace.WriteLine("Install success");
                                    continue;
                                }
                                catch (InstallerException e)
                                {
                                    Trace.WriteLine("Install failed");
                                    InstallState.Fail("Failed to install drivers: " + e.ErrorMessage);
                                    continue;
                                }
                            }
                            else
                            {
                                if ((!InstallState.DriversPlaced) && InstallState.NotRebooted)
                                {
                                    DriversMsi.repair();
                                    Trace.WriteLine("Repair done");
                                    InstallState.DriversPlaced = true;
                                    InstallState.NeedsReboot   = true;
                                    InstallState.Polling       = true;
                                    continue;
                                }
                                else
                                {
                                    Trace.WriteLine("Repair not needed");
                                }
                            }
                            if (!InstallState.RebootNow)
                            {
                                Trace.WriteLine("Wait to see if drivers initialize");
                                int noneedtoreboot = (int)Application.CommonAppDataRegistry.GetValue("DriverFinalReboot", 0);
                                if (noneedtoreboot == 0)
                                {
                                    Trace.WriteLine("Pool - I don't know if I have to reboot");
                                    InstallState.Polling = true;
                                }
                                else
                                {
                                    Trace.WriteLine("Don't poll, I have to reboot");
                                    InstallState.RebootNow = true;
                                }
                            }
                        }
                    }
                    else
                    {
                        Trace.WriteLine("No DriverMSI work");
                    }


                    if ((!InstallState.NsisFree) && (!InstallState.NsisUninstalling))
                    {
                        Trace.WriteLine("Checking NSIS");
                        if (InstallerNSIS.installed())
                        {
                            Trace.WriteLine("NSIS is installed, and needs to be removed");
                            if (InstallState.RebootReady)
                            {
                                Trace.WriteLine("Removing NSIS");
                                Vif.CopyPV();
                                Trace.WriteLine("Attempting NSIS Uninstall");
                                InstallState.NsisUninstalling = true;
                                InstallState.RebootNow        = true;
                            }
                            else
                            {
                                Trace.WriteLine("We'll remove NSIS next reboot");
                                InstallState.RebootNow = true;
                            }
                        }
                        else
                        {
                            Trace.WriteLine("No NSIS based installer found");
                            if (HWID.needsupdate())
                            {
                                Vif.CopyPV();
                                Trace.WriteLine("Attempting legacy Install");
                                try
                                {
                                    RegistryKey classes = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Class");
                                    foreach (String classuuid in classes.GetSubKeyNames())
                                    {
                                        Trace.WriteLine("Examining " + classuuid);
                                        RegistryKey classkey = classes.OpenSubKey(classuuid, true);
                                        string[]    filters  = (string[])classkey.GetValue("UpperFilters");
                                        if (filters != null)
                                        {
                                            Trace.WriteLine("UpperFilters Exists");
                                            List <string> newfilters = new List <String>();
                                            foreach (String filter in filters)
                                            {
                                                if (filter.ToUpper() != "XENFILT")
                                                {
                                                    newfilters.Add(filter);
                                                }
                                                else
                                                {
                                                    Trace.WriteLine("Removing XENFILT");
                                                }
                                            }
                                            if (newfilters.Count > 0)
                                            {
                                                if (newfilters.Count < filters.Length)
                                                {
                                                    Trace.WriteLine("Updating UpperFilters");
                                                    classkey.SetValue("UpperFilters", newfilters.ToArray(), RegistryValueKind.MultiString);
                                                }
                                            }
                                            else
                                            {
                                                classkey.DeleteValue("UpperFilters");
                                            }
                                        }
                                        else
                                        {
                                            Trace.WriteLine("UpperFilters not found");
                                        }
                                    }
                                }
                                catch
                                {
                                    Trace.WriteLine("Removing xenfilt from UpperFilters entries failed");
                                }
                                if (DriversMsi.installed())
                                {
                                    DriversMsi.uninstall();
                                }
                                if (AgentMsi.installed())
                                {
                                    AgentMsi.uninstall();
                                }

                                InstallState.NsisUninstalling = true;
                                InstallState.RebootNow        = true;
                            }
                            InstallState.NsisFree = true;
                        }
                    }
                    else
                    {
                        Trace.WriteLine("No NSIS work");
                    }

                    if (InstallWizard.InstallerState.WinVersion.isServerSKU())
                    {
                        if ((!InstallState.GotVssProvider) && (InstallState.NsisFree) && (!InstallState.NsisUninstalling))
                        {
                            Trace.WriteLine("Checking Vss Provider");
                            if (!VssProvMsi.installed())
                            {
                                Trace.WriteLine("Vss Provider not found, installing");
                                Trace.WriteLine(VssProvMsi.ToString());
                                try
                                {
                                    VssProvMsi.install("INSTALLDIR=" + installdir, "vssprov1msi", InstallState);
                                }
                                catch (InstallerException e)
                                {
                                    InstallState.Fail("Failed to install Vss  Provider : " + e.ErrorMessage);
                                    continue;
                                }
                            }
                            else if (VssProvMsi.olderinstalled())
                            {
                                Trace.WriteLine("Old Vss Provider found, updating");
                                try
                                {
                                    VssProvMsi.install("INSTALLDIR=" + installdir, "vssprov2msi", InstallState);
                                }
                                catch (InstallerException e)
                                {
                                    InstallState.Fail("Failed to install Vss Provider : " + e.ErrorMessage);
                                    continue;
                                }
                            }
                            else
                            {
                                Trace.WriteLine("Correct Vss Provider found");
                                InstallState.GotVssProvider = true;
                            }
                        }
                        else
                        {
                            Trace.WriteLine("No VSS Work");
                        }
                    }
                    else
                    {
                        Trace.WriteLine("No ServerSKU Work");
                    }

                    if ((!InstallState.GotAgent) && (InstallState.NsisFree) && (!InstallState.NsisUninstalling))
                    {
                        Trace.WriteLine("Checking Agent");
                        if (!AgentMsi.installed())
                        {
                            Trace.WriteLine("Agent not found, installing");
                            Trace.WriteLine(AgentMsi.ToString());
                            try
                            {
                                AgentMsi.install("INSTALLDIR=" + installdir, "agent1msi", InstallState);
                            }
                            catch (InstallerException e)
                            {
                                InstallState.Fail("Failed to install Guest Agent : " + e.ErrorMessage);
                                continue;
                            }
                        }
                        else if (AgentMsi.olderinstalled())
                        {
                            Trace.WriteLine("Old Agent found, updating");
                            try
                            {
                                AgentMsi.install("INSTALLDIR=" + installdir, "agent2msi", InstallState);
                            }
                            catch (InstallerException e)
                            {
                                InstallState.Fail("Failed to install Guest Agent : " + e.ErrorMessage);
                                continue;
                            }
                        }
                        else
                        {
                            Trace.WriteLine("Correct Agent found");
                            InstallState.GotAgent = true;
                        }
                    }
                    else
                    {
                        Trace.WriteLine("No Agent Work");
                    }

                    if (InstallState.Polling)
                    {
                        if (InstallState.PollTimedOut)
                        {
                            Trace.WriteLine("Polling timed out");
                            InstallState.RebootNow   = true;
                            InstallState.NeedsReboot = false;
                            InstallState.Polling     = false;
                        }
                        else
                        {
                            prog["tempscore"][1] += 1;
                            prog["tempscore"][0] += 1;
                            InstallState.Sleep(5000);
                        }
                    }
                    else
                    {
                        Trace.WriteLine("No Polling Work");
                    }

                    if ((!InstallState.RebootReady) && InstallState.RebootNow && InstallState.Unchanged)
                    {
                        // We are ready to reboot
                        Trace.WriteLine("Ready to reboot");
                        InstallState.Polling       = false;
                        InstallState.RebootDesired = true;
                        if (InstallState.WaitForShutdown())
                        {
                            Trace.WriteLine("Shutdown occuring");
                        }
                        continue;
                    }
                    else
                    {
                        Trace.WriteLine("No rebootready work");
                    }

                    if (InstallState.RebootReady && InstallState.RebootNow && InstallState.Unchanged)
                    {
                        Trace.WriteLine("Expecting Reboot /  Shutdown");
                        InstallState.Rebooting = true;
                        if (InstallState.NsisUninstalling)
                        {
                            // We have to do the HWID check before NSIS is uninstalled, but
                            // when we know NSIS is about to be uninstalled.
                            //
                            // NSIS leads to a blue screen if it doesn't have the right HWID at start of day
                            //
                            if ((!InstallState.GotDrivers) && (!InstallState.HWIDCorrect))
                            {
                                Trace.WriteLine("Checking HWID");
                                if (HWID.needsupdate())
                                {
                                    Trace.WriteLine("HWID Needs updating");
                                    try
                                    {
                                        if (!HWID.update())
                                        {
                                            InstallState.Fail("Unable to enable Xeniface WMI Client when trying to change device id");
                                        }
                                        Trace.WriteLine("HWID should be changed following next reboot");
                                    }
                                    catch (ManagementException)
                                    {
                                        //This suggests we don't have a WMI interface.  update nsis and try again
                                        InstallState.NsisUninstalling = false;
                                    }
                                }
                                else
                                {
                                    Trace.WriteLine("Correct HWID Found");
                                    InstallState.HWIDCorrect = true;
                                }
                            }
                            // Irritatingly, the NSIS installer continues running for longer than the
                            // lifetime of the uninstall.exe process.  Since we don't want to reboot
                            // while it (or its unattached children) are still running, we rely on
                            // the NSIS uninstaller to perform its own reboot, when it is done.
                            if (InstallState.NsisUninstalling)
                            {
                                InstallerNSIS.uninstall();
                            }
                            else
                            {
                                //DriverPackage.addcerts(InstallerNSIS.path);
                                InstallerNSIS.update();

                                //NSIS returns the same errorlevel for 'failure to install' and for
                                // 'needs a reboot to install'.  So we have to presume the install
                                // was a success.
                            }
                            InstallState.RebootNow = false;
                            InstallState.Done      = true;
                        }
                        else
                        {
                            InstallState.Done      = true;
                            InstallState.RebootNow = false;
                            InstallState.DoShutdown();
                        }
                    }
                    else
                    {
                        Trace.WriteLine("No Shutdown work");
                    }
                }

                Trace.WriteLine("Exited install cycle " + InstallState.Failed + " " + InstallState.RebootCount + " " + InstallState.Done);

                if (!InstallState.Passive)
                {
                    // We want to wait until the user terminates the GUI installer before shutting down the service
                    InstallState.WaitForDone();
                }

                if (InstallState.Installed || InstallState.Cancelled || InstallState.Failed)
                {
                    Trace.WriteLine("Installed " + InstallState.Installed + " Cancelled " + InstallState.Cancelled + " Failed " + InstallState.Failed);

                    try
                    {
                        Registry.LocalMachine.OpenSubKey(@"Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("Run", true).DeleteValue("CitrixXenAgentInstaller");
                    }
                    catch (Exception e)
                    {
                        if (!InstallState.Passive)
                        {
                            Trace.WriteLine("Failed to remove install agent run subkey: " + e.ToString());
                            InstallState.Fail("Failed to remove install agent subkey");
                        }
                    }
                    Trace.WriteLine("Turn off DriverFinalReboot");
                    Application.CommonAppDataRegistry.SetValue("DriverFinalReboot", 0);
                    Registry.SetValue(@"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\XenPVInstall", "Start", 3);
                    (new Thread(delegate()
                    {
                        this.Stop();
                    })).Start();
                }
            }
            catch (Exception e)
            {
                Trace.WriteLine("Install exception :" + e.ToString());
                InstallState.Fail("Failed to install due to exception" + e.ToString());
                if (!InstallState.Passive)
                {
                    // We want to wait until the user terminates the GUI installer before shutting down the service

                    InstallState.WaitForDone();
                }
                try
                {
                    Registry.LocalMachine.OpenSubKey(@"Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("Run", true).DeleteValue("CitrixXenAgentInstaller");
                }
                catch {
                    Trace.WriteLine("Failed to remove install agent run subkey (error state)");
                    InstallState.Fail("Failed to remove install agent subkey");
                }
            }
        }
Beispiel #3
0
        void InstallThreadHandler()
        {
            try
            {
                Trace.WriteLine("Thread");
                Assembly curAssm;
                curAssm = Assembly.GetAssembly(this.GetType());
                int  registertimeout = 0;
                bool wmiregistered   = false;
                while (registertimeout < 30 * 1000)
                {
                    Trace.WriteLine("Try to register WMI");
                    try
                    {
                        if (System.Management.Instrumentation.Instrumentation.IsAssemblyRegistered(curAssm))
                        {
                            //Cool; it's already registered in WMI
                            Trace.WriteLine("Already registered");
                            wmiregistered = true;
                            break;
                        }
                        else //Well then, register it
                        {
                            Trace.WriteLine("Ensure we are registered with WMI");

                            System.Management.Instrumentation.Instrumentation.RegisterAssembly(curAssm);
                            wmiregistered = true;
                            break;
                        }
                    }
                    catch (ManagementException)
                    {
                        Trace.WriteLine("Waiting for WMI to initialise");
                        Thread.Sleep(500);
                        registertimeout += 500;
                    }
                    catch (Exception e)
                    {
                        Trace.WriteLine("WMI initialisation not finished (" + e.ToString() + ")");
                        Thread.Sleep(500);
                        registertimeout += 500;
                    }
                }
                if (!wmiregistered)
                {
                    Trace.WriteLine("Unable to contact WMI");
                    InstallState.Fail("Unable to contact WMI");
                }
                Trace.WriteLine("Got WMI connection");
                CitrixXenServerInstallStatus installstatusclass = new CitrixXenServerInstallStatus(InstallState);
                Trace.WriteLine("got status");
                try
                {
                    Instrumentation.Publish(installstatusclass);
                }
                catch (Exception e)
                {
                    Trace.WriteLine(e.ToString());
                    throw;
                }
                Trace.WriteLine("Begin");
                while (InstallState.PauseOnStart)
                {
                    Trace.WriteLine("Paused");
                    Thread.Sleep(1000);
                    try
                    {
                        int pausestate = (int)Application.CommonAppDataRegistry.GetValue("Continue", 0);
                        if (pausestate != 0)
                        {
                            break;
                        }
                    }
                    catch { };
                }
                ;
                InstallState.MaxProgress = 100;
                InstallState.Progress    = 1;
                Trace.WriteLine("Initializing Install =======================================");

                InstallerState.ExistingDriverInstalling = false;
                uint res = setupapi.CMP_WaitNoPendingInstallEvents(0);
                if (res == setupapi.WAIT_TIMEOUT || res == setupapi.WAIT_FAILED)
                {
                    InstallerState.ExistingDriverInstalling = true;
                    Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "existingDriverInstalling", 1, RegistryValueKind.DWord);
                }
                Trace.WriteLine("check reg");
                Object regval = Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "existingDriverInstalling", 0);

                if (regval != null && ((int)regval) == 1)
                {
                    Trace.WriteLine("set from reg");
                    InstallerState.ExistingDriverInstalling = true;
                }
                Trace.WriteLine("reg done");

                DriverPackage DriversMsi;
                MsiInstaller  VssProvMsi;
                MsiInstaller  AgentMsi;
                string        installdir;
                NSISItem      InstallerNSIS;
                if (is64BitOS())
                {
                    Trace.WriteLine("64 Bit Install");
                    installdir = (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Citrix\\XenToolsInstaller", "Install_Dir", Application.StartupPath);
                    DriversMsi = new DriverPackage((string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath), Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath) + "citrixxendriversx64.msi");
                    VssProvMsi = new MsiInstaller(Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath) + "citrixvssx64.msi");
                    AgentMsi   = new MsiInstaller(Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath) + "citrixguestagentx64.msi");

                    InstallerNSIS = new NSISItem("Citrix XenTools", (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath));
                }
                else
                {
                    Trace.WriteLine("32 Bit Install");
                    installdir = (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "Install_Dir", Application.StartupPath);
                    DriversMsi = new DriverPackage((string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath), Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath) + "citrixxendriversx86.msi");
                    VssProvMsi = new MsiInstaller(Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath) + "citrixvssx86.msi");
                    AgentMsi   = new MsiInstaller(Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath) + "citrixguestagentx86.msi");

                    InstallerNSIS = new NSISItem("Citrix XenTools", (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", "MSISourceDir", Application.StartupPath));
                }
                installdir = "\"" + installdir + "\"";

                VifConfig Vif = new VifConfig();
                Trace.WriteLine("Entering state loop");
                Dictionary <string, int[]> prog = new Dictionary <string, int[]>();

                prog["installscore"]     = new int[] { 300, 0 };
                prog["tempscore"]        = new int[] { 0, 0 };
                InstallState.MaxProgress = prog["installscore"][0];

                if (InstallService.isWOW64())
                {
                    Trace.WriteLine("Install failed");
                    InstallState.Fail("PV Tools cannot be installed on systems where .Net applications are forced to run under WoW64\n\nSet HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NetFramework\\Enable64Bit to 1 and attempt the install again.");
                }

                while ((!InstallState.Failed) && (InstallState.RebootCount > 0) && (!InstallState.Done))
                {
                    InstallState.Unchanged  = true;
                    prog["installscore"][1] = 0;
                    if (InstallState.GotAgent)
                    {
                        prog["installscore"][1] += 100;
                    }
                    if (InstallState.NsisFree)
                    {
                        prog["installscore"][1] += 100;
                    }
                    if (InstallState.GotDrivers)
                    {
                        prog["installscore"][1] += 100;
                    }
                    InstallState.MaxProgress = prog["installscore"][0] + prog["tempscore"][0];
                    InstallState.Progress    = prog["installscore"][1] + prog["tempscore"][1];

                    if (InstallState.GotAgent &&
                        ((InstallWizard.InstallerState.WinVersion.isServerSKU() && InstallState.GotVssProvider) || !InstallWizard.InstallerState.WinVersion.isServerSKU()) &&
                        InstallState.GotDrivers &&
                        !InstallState.RebootNow &&
                        InstallState.NsisFree &&
                        !InstallState.NeedsReboot)
                    {
                        Trace.WriteLine("Everything is installed");
                        InstallState.Installed = true;
                        InstallState.Done      = true;
                        continue;
                    }

                    if ((!InstallState.GotDrivers) && (InstallState.NsisFree))
                    {
                        Trace.WriteLine("Check if drivers are functioning");

                        string oldtext = InstallState.DriverText;

                        if ((DriversMsi.installed() && (!DriversMsi.olderinstalled())) && DriversMsi.functioning(ref InstallState.DriverText))
                        {
                            Trace.WriteLine("Drivers functioning");
                            InstallState.GotDrivers = true;
                        }
                        else
                        {
                            if (InstallState.DriverText != oldtext)
                            {
                                InstallState.PollingReset();
                            }
                            if ((!InstallState.DriversPlaced) && ((!DriversMsi.installed()) || DriversMsi.olderinstalled()))
                            {
                                Trace.WriteLine("Driver install package not found");
                                Trace.WriteLine("Attempt driver install");
                                Trace.WriteLine(DriversMsi.ToString());

                                if (DriversMsi.olderinstalled())
                                {
                                }

                                try
                                {
                                    DriversMsi.install("INSTALLDIR=" + installdir, "driversmsi", InstallState);
                                    InstallState.DriversPlaced = true;
                                    InstallState.NeedsReboot   = true;
                                    InstallState.Polling       = true;
                                    Trace.WriteLine("Install success");
                                    continue;
                                }
                                catch (InstallerException e)
                                {
                                    Trace.WriteLine("Install failed");
                                    InstallState.Fail("Failed to install drivers: " + e.ErrorMessage);
                                    continue;
                                }
                            }
                            else
                            {
                                if ((!InstallState.DriversPlaced) && InstallState.NotRebooted)
                                {
                                    DriversMsi.repair();
                                    Trace.WriteLine("Repair done");
                                    InstallState.DriversPlaced = true;
                                    InstallState.NeedsReboot   = true;
                                    InstallState.Polling       = true;
                                    continue;
                                }
                                else
                                {
                                    Trace.WriteLine("Repair not needed");
                                }
                            }
                            if (!InstallState.RebootNow)
                            {
                                Trace.WriteLine("Wait to see if drivers initialize");
                                int noneedtoreboot = (int)Application.CommonAppDataRegistry.GetValue("DriverFinalReboot", 0);
                                if (noneedtoreboot == 0)
                                {
                                    Trace.WriteLine("Pool - I don't know if I have to reboot");
                                    InstallState.Polling = true;
                                }
                                else
                                {
                                    Trace.WriteLine("Don't poll, I have to reboot");
                                    InstallState.RebootNow = true;
                                }
                            }
                        }
                    }
                    else
                    {
                        Trace.WriteLine("No DriverMSI work");
                    }


                    if ((!InstallState.NsisFree) && (!InstallState.NsisHandlingRequired))
                    {
                        Trace.WriteLine("Checking NSIS");
                        if (InstallerNSIS.installed() || InstallerNSIS.nsisPartiallyInstalled())
                        {
                            Trace.WriteLine("NSIS is installed, and needs to be removed");
                            if (InstallState.RebootReady)
                            {
                                Trace.WriteLine("Removing NSIS");
                                Vif.CopyPV();
                                Trace.WriteLine("Attempting NSIS Uninstall");
                                InstallState.NsisHandlingRequired = true;
                                InstallState.RebootNow            = true;
                            }
                            else
                            {
                                Trace.WriteLine("We'll remove NSIS next reboot");
                                InstallState.RebootNow = true;
                            }
                        }
                        else
                        {
                            Trace.WriteLine("No NSIS based installer found");
                            InstallState.NsisFree = true;
                        }
                    }
                    else
                    {
                        Trace.WriteLine("No NSIS work");
                    }

                    if (DriverPackage.unknownDeviceInstalled())
                    {
                        InstallState.Fail("Unknown PV drivers installed on system.  Uninstall PV drivers and retry");
                        continue;
                    }


                    if (InstallWizard.InstallerState.WinVersion.isServerSKU())
                    {
                        if ((!InstallState.GotVssProvider) && (InstallState.NsisFree) && (!InstallState.NsisHandlingRequired))
                        {
                            Trace.WriteLine("Checking Vss Provider");
                            if (!VssProvMsi.installed())
                            {
                                Trace.WriteLine("Vss Provider not found, installing");
                                Trace.WriteLine(VssProvMsi.ToString());
                                try
                                {
                                    VssProvMsi.install("INSTALLDIR=" + installdir, "vssprov1msi", InstallState);
                                }
                                catch (InstallerException e)
                                {
                                    InstallState.Fail("Failed to install Vss  Provider : " + e.ErrorMessage);
                                    continue;
                                }
                            }
                            else if (VssProvMsi.olderinstalled())
                            {
                                Trace.WriteLine("Old Vss Provider found, updating");
                                try
                                {
                                    VssProvMsi.install("INSTALLDIR=" + installdir, "vssprov2msi", InstallState);
                                }
                                catch (InstallerException e)
                                {
                                    InstallState.Fail("Failed to install Vss Provider : " + e.ErrorMessage);
                                    continue;
                                }
                            }
                            else
                            {
                                Trace.WriteLine("Correct Vss Provider found");
                                InstallState.GotVssProvider = true;
                            }
                        }
                        else
                        {
                            Trace.WriteLine("No VSS Work");
                        }
                    }
                    else
                    {
                        Trace.WriteLine("No ServerSKU Work");
                    }

                    if ((!InstallState.GotAgent) && (InstallState.NsisFree) && (!InstallState.NsisHandlingRequired))
                    {
                        Trace.WriteLine("Checking Agent");
                        if (!AgentMsi.installed())
                        {
                            Trace.WriteLine("Agent not found, installing");
                            Trace.WriteLine(AgentMsi.ToString());
                            try
                            {
                                AgentMsi.install("INSTALLDIR=" + installdir, "agent1msi", InstallState);
                            }
                            catch (InstallerException e)
                            {
                                InstallState.Fail("Failed to install Guest Agent : " + e.ErrorMessage);
                                continue;
                            }
                        }
                        else if (AgentMsi.olderinstalled())
                        {
                            Trace.WriteLine("Old Agent found, updating");
                            try
                            {
                                AgentMsi.install("INSTALLDIR=" + installdir, "agent2msi", InstallState);
                            }
                            catch (InstallerException e)
                            {
                                InstallState.Fail("Failed to install Guest Agent : " + e.ErrorMessage);
                                continue;
                            }
                        }
                        else
                        {
                            Trace.WriteLine("Correct Agent found");
                            InstallState.GotAgent = true;
                        }
                    }
                    else
                    {
                        Trace.WriteLine("No Agent Work");
                    }

                    if (InstallState.Polling)
                    {
                        if (InstallState.PollTimedOut)
                        {
                            Trace.WriteLine("Polling timed out");
                            InstallState.RebootNow   = true;
                            InstallState.NeedsReboot = false;
                            InstallState.Polling     = false;
                        }
                        else
                        {
                            prog["tempscore"][1] += 1;
                            prog["tempscore"][0] += 1;
                            InstallState.Sleep(5000);
                        }
                    }
                    else
                    {
                        Trace.WriteLine("No Polling Work");
                    }

                    if ((!InstallState.RebootReady) && InstallState.RebootNow && InstallState.Unchanged)
                    {
                        // We are ready to reboot
                        Trace.WriteLine("Is anything preventing us from shutting down?");
                        if (InstallerState.ExistingDriverInstalling)
                        {
                            setupapi.CMP_WaitNoPendingInstallEvents(1000 * 20 * 60);
                        }
                        else
                        {
                            setupapi.CMP_WaitNoPendingInstallEvents(setupapi.INFINITE);
                        }

                        Trace.WriteLine("Ready to reboot");
                        InstallState.Polling       = false;
                        InstallState.RebootDesired = true;
                        if (InstallState.WaitForShutdown())
                        {
                            Trace.WriteLine("Shutdown occuring");
                        }
                        continue;
                    }
                    else
                    {
                        Trace.WriteLine("No rebootready work");
                    }

                    if (InstallState.RebootReady && InstallState.RebootNow && InstallState.Unchanged)
                    {
                        Trace.WriteLine("Expecting Reboot /  Shutdown");
                        InstallState.Rebooting = true;
                        if (InstallState.NsisHandlingRequired)
                        {
                            // Irritatingly, the NSIS installer continues running for longer than the
                            // lifetime of the uninstall.exe process.  Since we don't want to reboot
                            // while it (or its unattached children) are still running, we rely on
                            // the NSIS uninstaller to perform its own reboot, when it is done.
                            //
                            // We want to update George or earlier installers, as they don't
                            // uninstall silently
                            if (InstallerNSIS.installed() &&
                                ((InstallerNSIS.majorVersion() > 5) ||
                                 ((InstallerNSIS.majorVersion() == 5) && (InstallerNSIS.minorVersion() > 5))))
                            {
                                InstallerNSIS.uninstall();
                            }
                            else
                            {
                                // NSIS is installed, but the install is corrupt and the uninstaller can't be located
                                InstallerNSIS.update();

                                //NSIS returns the same errorlevel for 'failure to install' and for
                                // 'needs a reboot to install'.  So we have to presume the install
                                // was a success.
                            }
                            InstallState.RebootNow = false;
                            InstallState.Done      = true;
                        }
                        else
                        {
                            InstallState.Done      = true;
                            InstallState.RebootNow = false;
                            InstallState.DoShutdown();
                        }
                    }
                    else
                    {
                        Trace.WriteLine("No Shutdown work");
                    }
                }

                Trace.WriteLine("Exited install cycle " + InstallState.Failed + " " + InstallState.RebootCount + " " + InstallState.Done);

                if (!InstallState.Passive)
                {
                    // We want to wait until the user terminates the GUI installer before shutting down the service
                    InstallState.WaitForDone();
                }

                if (InstallState.Installed || InstallState.Cancelled || InstallState.Failed)
                {
                    Trace.WriteLine("Installed " + InstallState.Installed + " Cancelled " + InstallState.Cancelled + " Failed " + InstallState.Failed);

                    try
                    {
                        Registry.LocalMachine.OpenSubKey(@"Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("Run", true).DeleteValue("CitrixXenAgentInstaller");
                    }
                    catch (Exception e)
                    {
                        if (!InstallState.Passive)
                        {
                            Trace.WriteLine("Failed to remove install agent run subkey: " + e.ToString());
                            InstallState.Fail("Failed to remove install agent subkey");
                        }
                    }
                    Trace.WriteLine("Turn off DriverFinalReboot");
                    Application.CommonAppDataRegistry.SetValue("DriverFinalReboot", 0);

                    try
                    {
                        Registry.LocalMachine.OpenSubKey(@"HKEY_LOCAL_MACHINE\\SOFTWARE\\Citrix\\XenToolsInstaller", true).DeleteValue("existingDriverInstalling");
                    }
                    catch
                    {
                    }

                    Registry.SetValue(@"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\XenPVInstall", "Start", 3);
                    (new Thread(delegate()
                    {
                        this.Stop();
                    })).Start();
                }
            }
            catch (Exception e)
            {
                Trace.WriteLine("Install exception :" + e.ToString());
                InstallState.Fail("Failed to install due to exception" + e.ToString());
                if (!InstallState.Passive)
                {
                    // We want to wait until the user terminates the GUI installer before shutting down the service

                    InstallState.WaitForDone();
                }
                try
                {
                    Registry.LocalMachine.OpenSubKey(@"Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("Run", true).DeleteValue("CitrixXenAgentInstaller");
                }
                catch {
                    Trace.WriteLine("Failed to remove install agent run subkey (error state)");
                    InstallState.Fail("Failed to remove install agent subkey");
                }
            }
        }
Beispiel #4
0
        public AmcacheNew(string hive, bool recoverDeleted)
        {
            _logger = LogManager.GetCurrentClassLogger();

            var reg = new RegistryHive(hive)
            {
                RecoverDeleted = recoverDeleted
            };

            reg.ParseHive();

            var fileKey     = reg.GetKey(@"Root\InventoryApplicationFile");
            var programsKey = reg.GetKey(@"Root\InventoryApplication");


            UnassociatedFileEntries = new List <FileEntryNew>();
            ProgramsEntries         = new List <ProgramsEntryNew>();
            DeviceContainers        = new List <DeviceContainer>();
            DevicePnps     = new List <DevicePnp>();
            DriveBinaries  = new List <DriverBinary>();
            DriverPackages = new List <DriverPackage>();
            ShortCuts      = new List <Shortcut>();

            if (fileKey == null || programsKey == null)
            {
                _logger.Error(
                    "Hive does not contain a InventoryApplicationFile and/or InventoryApplication key. Processing cannot continue");
                return;
            }


            foreach (var registryKey in programsKey.SubKeys)
            {
                var            bundleManifestPath = string.Empty;
                var            hiddenArp          = false;
                var            inboxModernApp     = false;
                DateTimeOffset?installDate        = null;
                var            language           = 0;
                var            manifestPath       = string.Empty;
                var            msiPackageCode     = string.Empty;
                var            msiProductCode     = string.Empty;
                var            name = string.Empty;
                var            osVersionAtInstallTime = string.Empty;
                var            packageFullName        = string.Empty;
                var            programId         = string.Empty;
                var            programInstanceId = string.Empty;
                var            publisher         = string.Empty;
                var            registryKeyPath   = string.Empty;
                var            rootDirPath       = string.Empty;
                var            source            = string.Empty;
                var            storeAppType      = string.Empty;
                var            type            = string.Empty;
                var            uninstallString = string.Empty;
                var            version         = string.Empty;


                try
                {
                    foreach (var registryKeyValue in registryKey.Values)
                    {
                        switch (registryKeyValue.ValueName)
                        {
                        case "BundleManifestPath":
                            bundleManifestPath = registryKeyValue.ValueData;
                            break;

                        case "HiddenArp":
                            hiddenArp = registryKeyValue.ValueData == "1";
                            break;

                        case "InboxModernApp":
                            inboxModernApp = registryKeyValue.ValueData == "1";
                            break;

                        case "InstallDate":
                            if (registryKeyValue.ValueData.Length > 0)
                            {
                                var d = new DateTimeOffset(DateTime.Parse(registryKeyValue.ValueData).Ticks,
                                                           TimeSpan.Zero);
                                installDate = d;
                            }
                            break;

                        case "Language":
                            language = int.Parse(registryKeyValue.ValueData);
                            break;

                        case "ManifestPath":
                            manifestPath = registryKeyValue.ValueData;
                            break;

                        case "MsiPackageCode":
                            msiPackageCode = registryKeyValue.ValueData;
                            break;

                        case "MsiProductCode":
                            msiProductCode = registryKeyValue.ValueData;
                            break;

                        case "Name":
                            name = registryKeyValue.ValueData;
                            break;

                        case "OSVersionAtInstallTime":
                            osVersionAtInstallTime = registryKeyValue.ValueData;
                            break;

                        case "PackageFullName":
                            packageFullName = registryKeyValue.ValueData;
                            break;

                        case "ProgramId":
                            programId = registryKeyValue.ValueData;
                            break;

                        case "ProgramInstanceId":
                            programInstanceId = registryKeyValue.ValueData;
                            break;

                        case "Publisher":
                            publisher = registryKeyValue.ValueData;
                            break;

                        case "RegistryKeyPath":
                            registryKeyPath = registryKeyValue.ValueData;
                            break;

                        case "RootDirPath":
                            rootDirPath = registryKeyValue.ValueData;
                            break;

                        case "Source":
                            source = registryKeyValue.ValueData;
                            break;

                        case "StoreAppType":
                            storeAppType = registryKeyValue.ValueData;
                            break;

                        case "Type":
                            type = registryKeyValue.ValueData;
                            break;

                        case "UninstallString":
                            uninstallString = registryKeyValue.ValueData;
                            break;

                        case "Version":
                            version = registryKeyValue.ValueData;
                            break;

                        default:
                            _logger.Warn(
                                $"Unknown value name in InventoryApplication at path {registryKey.KeyPath}: {registryKeyValue.ValueName}");
                            break;
                        }
                    }

                    var pe = new ProgramsEntryNew(bundleManifestPath, hiddenArp, inboxModernApp, installDate, language,
                                                  manifestPath, msiPackageCode, msiProductCode, name, osVersionAtInstallTime, packageFullName,
                                                  programId, programInstanceId, publisher, registryKeyPath, rootDirPath, source, storeAppType,
                                                  type, uninstallString, version, registryKey.LastWriteTime.Value);

                    ProgramsEntries.Add(pe);
                }
                catch (Exception ex)
                {
                    _logger.Error($"Error parsing ProgramsEntry at {registryKey.KeyPath}. Error: {ex.Message}");
                    _logger.Error(
                        $"Please send the following text to [email protected]. \r\n\r\nKey data: {registryKey}");
                }
            }

            foreach (var subKey in fileKey.SubKeys)
            {
                var            binaryType        = string.Empty;
                var            binFileVersion    = string.Empty;
                var            binProductVersion = string.Empty;
                var            fileId            = string.Empty;
                var            isOsComponent     = false;
                var            isPeFile          = false;
                var            language          = 0;
                DateTimeOffset?linkDate          = null;
                var            longPathHash      = string.Empty;
                var            lowerCaseLongPath = string.Empty;
                var            name           = string.Empty;
                var            productName    = string.Empty;
                var            productVersion = string.Empty;
                var            programId      = string.Empty;
                var            publisher      = string.Empty;
                var            size           = 0;
                var            version        = string.Empty;

                var hasLinkedProgram = false;

                try
                {
                    foreach (var subKeyValue in subKey.Values)
                    {
                        switch (subKeyValue.ValueName)
                        {
                        case "BinaryType":
                            binaryType = subKeyValue.ValueData;
                            break;

                        case "BinFileVersion":
                            binFileVersion = subKeyValue.ValueData;
                            break;

                        case "BinProductVersion":
                            binProductVersion = subKeyValue.ValueData;
                            break;

                        case "FileId":
                            fileId = subKeyValue.ValueData;
                            break;

                        case "IsOsComponent":
                            isOsComponent = subKeyValue.ValueData == "1";
                            break;

                        case "IsPeFile":
                            isPeFile = subKeyValue.ValueData == "1";
                            break;

                        case "Language":
                            language = int.Parse(subKeyValue.ValueData);
                            break;

                        case "LinkDate":
                            if (subKeyValue.ValueData.Length > 0)
                            {
                                var d = new DateTimeOffset(DateTime.Parse(subKeyValue.ValueData).Ticks,
                                                           TimeSpan.Zero);
                                linkDate = d;
                            }


                            break;

                        case "LongPathHash":
                            longPathHash = subKeyValue.ValueData;
                            break;

                        case "LowerCaseLongPath":
                            lowerCaseLongPath = subKeyValue.ValueData;
                            break;

                        case "Name":
                            name = subKeyValue.ValueData;
                            break;

                        case "ProductName":
                            productName = subKeyValue.ValueData;
                            break;

                        case "ProductVersion":
                            productVersion = subKeyValue.ValueData;
                            break;

                        case "ProgramId":
                            programId = subKeyValue.ValueData;

                            var program = ProgramsEntries.SingleOrDefault(t => t.ProgramId == programId);
                            if (program != null)
                            {
                                hasLinkedProgram = true;
                            }
                            break;

                        case "Publisher":
                            publisher = subKeyValue.ValueData;
                            break;

                        case "Size":
                            size = int.Parse(subKeyValue.ValueData);
                            break;

                        case "Version":
                            version = subKeyValue.ValueData;
                            break;

                        default:
                            _logger.Warn(
                                $"Unknown value name when processing FileEntry at path '{subKey.KeyPath}': {subKeyValue.ValueName}");
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error($"Error parsing FileEntry at {subKey.KeyPath}. Error: {ex.Message}");
                    _logger.Error(
                        $"Please send the following text to [email protected]. \r\n\r\nKey data: {subKey}");
                }


                TotalFileEntries += 1;

                Debug.WriteLine(name);
                var fe = new FileEntryNew(binaryType, binFileVersion, productVersion, fileId, isOsComponent, isPeFile,
                                          language, linkDate, longPathHash, lowerCaseLongPath, name, productName, productVersion, programId,
                                          publisher, size, version, subKey.LastWriteTime.Value, binProductVersion);

                if (hasLinkedProgram)
                {
                    var program = ProgramsEntries.SingleOrDefault(t => t.ProgramId == fe.ProgramId);
                    fe.ApplicationName = program.Name;
                    program.FileEntries.Add(fe);
                }
                else
                {
                    fe.ApplicationName = "Unassociated";
                    UnassociatedFileEntries.Add(fe);
                }
            }


            var shortCutkey = reg.GetKey(@"Root\InventoryApplicationShortcut");

            if (shortCutkey != null)
            {
                foreach (var shortCutkeySubKey in shortCutkey.SubKeys)
                {
                    ShortCuts.Add(new Shortcut(shortCutkeySubKey.KeyName, shortCutkeySubKey.Values.First().ValueData,
                                               shortCutkeySubKey.LastWriteTime.Value));
                }
            }


            var deviceKey = reg.GetKey(@"Root\InventoryDeviceContainer");

            if (deviceKey != null)
            {
                foreach (var deviceSubKey in deviceKey.SubKeys)
                {
                    var categories         = string.Empty;
                    var discoveryMethod    = string.Empty;
                    var friendlyName       = string.Empty;
                    var icon               = string.Empty;
                    var isActive           = false;
                    var isConnected        = false;
                    var isMachineContainer = false;
                    var isNetworked        = false;
                    var isPaired           = false;
                    var manufacturer       = string.Empty;
                    var modelId            = string.Empty;
                    var modelName          = string.Empty;
                    var modelNumber        = string.Empty;
                    var primaryCategory    = string.Empty;
                    var state              = string.Empty;

                    try
                    {
                        foreach (var keyValue in deviceSubKey.Values)
                        {
                            switch (keyValue.ValueName)
                            {
                            case "Categories":
                                categories = keyValue.ValueData;
                                break;

                            case "DiscoveryMethod":
                                discoveryMethod = keyValue.ValueData;
                                break;

                            case "FriendlyName":
                                friendlyName = keyValue.ValueData;
                                break;

                            case "Icon":
                                icon = keyValue.ValueData;
                                break;

                            case "IsActive":
                                isActive = keyValue.ValueData == "1";
                                break;

                            case "IsConnected":
                                isConnected = keyValue.ValueData == "1";
                                break;

                            case "IsMachineContainer":
                                isMachineContainer = keyValue.ValueData == "1";
                                break;

                            case "IsNetworked":
                                isNetworked = keyValue.ValueData == "1";
                                break;

                            case "IsPaired":
                                isPaired = keyValue.ValueData == "1";
                                break;

                            case "Manufacturer":
                                manufacturer = keyValue.ValueData;
                                break;

                            case "ModelId":
                                modelId = keyValue.ValueData;
                                break;

                            case "ModelName":
                                modelName = keyValue.ValueData;
                                break;

                            case "ModelNumber":
                                modelNumber = keyValue.ValueData;
                                break;

                            case "PrimaryCategory":
                                primaryCategory = keyValue.ValueData;
                                break;

                            case "State":
                                state = keyValue.ValueData;
                                break;

                            default:
                                _logger.Warn(
                                    $"Unknown value name when processing DeviceContainer at path '{deviceSubKey.KeyPath}': {keyValue.ValueName}");
                                break;
                            }
                        }

                        var dc = new DeviceContainer(deviceSubKey.KeyName, deviceSubKey.LastWriteTime.Value, categories,
                                                     discoveryMethod, friendlyName, icon, isActive, isConnected, isMachineContainer, isNetworked,
                                                     isPaired, manufacturer, modelId, modelName, modelNumber, primaryCategory, state);

                        DeviceContainers.Add(dc);
                    }
                    catch (Exception ex)
                    {
                        _logger.Error($"Error parsing DeviceContainer at {deviceSubKey.KeyPath}. Error: {ex.Message}");
                        _logger.Error(
                            $"Please send the following text to [email protected]. \r\n\r\nKey data: {deviceSubKey}");
                    }
                }
            }


            var pnpKey = reg.GetKey(@"Root\InventoryDevicePnp");

            if (pnpKey != null)
            {
                foreach (var pnpsKey in pnpKey.SubKeys)
                {
                    var busReportedDescription = string.Empty;
                    var Class                   = string.Empty;
                    var classGuid               = string.Empty;
                    var compid                  = string.Empty;
                    var containerId             = string.Empty;
                    var description             = string.Empty;
                    var deviceState             = string.Empty;
                    var driverId                = string.Empty;
                    var driverName              = string.Empty;
                    var driverPackageStrongName = string.Empty;
                    var driverVerDate           = string.Empty;
                    var driverVerVersion        = string.Empty;
                    var enumerator              = string.Empty;
                    var hwid         = string.Empty;
                    var inf          = string.Empty;
                    var installState = string.Empty;
                    var manufacturer = string.Empty;
                    var matchingId   = string.Empty;
                    var model        = string.Empty;
                    var parentId     = string.Empty;
                    var problemCode  = string.Empty;
                    var provider     = string.Empty;
                    var service      = string.Empty;
                    var stackid      = string.Empty;

                    try
                    {
                        foreach (var keyValue in pnpsKey.Values)
                        {
                            switch (keyValue.ValueName)
                            {
                            case "BusReportedDescription":
                                busReportedDescription = keyValue.ValueData;
                                break;

                            case "Class":
                                Class = keyValue.ValueData;
                                break;

                            case "ClassGuid":
                                classGuid = keyValue.ValueData;
                                break;

                            case "COMPID":
                                compid = keyValue.ValueData;
                                break;

                            case "ContainerId":
                                containerId = keyValue.ValueData;
                                break;

                            case "Description":
                                description = keyValue.ValueData;
                                break;

                            case "DeviceState":
                                deviceState = keyValue.ValueData;
                                break;

                            case "DriverId":
                                driverId = keyValue.ValueData;
                                break;

                            case "DriverName":
                                driverName = keyValue.ValueData;
                                break;

                            case "DriverPackageStrongName":
                                driverPackageStrongName = keyValue.ValueData;
                                break;

                            case "DriverVerDate":
                                driverVerDate = keyValue.ValueData;
                                break;

                            case "DriverVerVersion":
                                driverVerVersion = keyValue.ValueData;
                                break;

                            case "Enumerator":
                                enumerator = keyValue.ValueData;
                                break;

                            case "HWID":
                                hwid = keyValue.ValueData;
                                break;

                            case "Inf":
                                inf = keyValue.ValueData;
                                break;

                            case "InstallState":
                                installState = keyValue.ValueData;
                                break;

                            case "LowerClassFilters":
                            case "LowerFilters":
                                break;

                            case "Manufacturer":
                                manufacturer = keyValue.ValueData;
                                break;

                            case "MatchingID":
                                matchingId = keyValue.ValueData;
                                break;

                            case "Model":
                                model = keyValue.ValueData;
                                break;

                            case "ParentId":
                                parentId = keyValue.ValueData;
                                break;

                            case "ProblemCode":
                                problemCode = keyValue.ValueData;
                                break;

                            case "Provider":
                                provider = keyValue.ValueData;
                                break;

                            case "Service":
                                service = keyValue.ValueData;
                                break;

                            case "STACKID":
                                stackid = keyValue.ValueData;
                                break;

                            case "UpperClassFilters":
                            case "UpperFilters":
                                break;

                            default:
                                _logger.Warn(
                                    $"Unknown value name when processing DevicePnp at path '{pnpsKey.KeyPath}': {keyValue.ValueName}");
                                break;
                            }
                        }

                        var dp = new DevicePnp(pnpsKey.KeyName, pnpKey.LastWriteTime.Value, busReportedDescription,
                                               Class, classGuid, compid, containerId, description, deviceState, driverId, driverName,
                                               driverPackageStrongName, driverVerDate, driverVerVersion, enumerator, hwid, inf,
                                               installState, manufacturer, matchingId, model, parentId, problemCode, provider, service,
                                               stackid);

                        DevicePnps.Add(dp);
                    }
                    catch (Exception ex)
                    {
                        _logger.Error($"Error parsing DevicePnp at {pnpKey.KeyPath}. Error: {ex.Message}");
                        _logger.Error(
                            $"Please send the following text to [email protected]. \r\n\r\nKey data: {pnpKey}");
                    }
                }
            }


            var binaryKey = reg.GetKey(@"Root\InventoryDriverBinary");

            if (binaryKey != null)
            {
                foreach (var binKey in binaryKey.SubKeys)
                {
                    var            driverCheckSum          = 0;
                    var            driverCompany           = string.Empty;
                    var            driverId                = string.Empty;
                    var            driverInBox             = false;
                    var            driverIsKernelMode      = false;
                    DateTimeOffset?driverLastWriteTime     = null;
                    var            driverName              = string.Empty;
                    var            driverPackageStrongName = string.Empty;
                    var            driverSigned            = false;
                    DateTimeOffset?driverTimeStamp         = null;
                    var            driverType              = string.Empty;
                    var            driverVersion           = string.Empty;
                    var            imageSize               = 0;
                    var            inf            = string.Empty;
                    var            product        = string.Empty;
                    var            productVersion = string.Empty;
                    var            service        = string.Empty;
                    var            wdfVersion     = string.Empty;


                    try
                    {
                        foreach (var keyValue in binKey.Values)
                        {
                            switch (keyValue.ValueName)
                            {
                            case "DriverCheckSum":
                                driverCheckSum = int.Parse(keyValue.ValueData);
                                break;

                            case "DriverCompany":
                                driverCompany = keyValue.ValueData;
                                break;

                            case "DriverId":
                                driverId = keyValue.ValueData;
                                break;

                            case "DriverInBox":
                                driverInBox = keyValue.ValueData == "1";
                                break;

                            case "DriverIsKernelMode":
                                driverIsKernelMode = keyValue.ValueData == "1";
                                break;

                            case "DriverLastWriteTime":
                                if (keyValue.ValueData.Length > 0)
                                {
                                    var d = new DateTimeOffset(DateTime.Parse(keyValue.ValueData).Ticks,
                                                               TimeSpan.Zero);
                                    driverLastWriteTime = d;
                                }

                                break;

                            case "DriverName":
                                driverName = keyValue.ValueData;
                                break;

                            case "DriverPackageStrongName":
                                driverPackageStrongName = keyValue.ValueData;
                                break;

                            case "DriverSigned":
                                driverSigned = keyValue.ValueData == "1";
                                break;

                            case "DriverTimeStamp":
                                //DateTimeOffset.FromUnixTimeSeconds(seca).ToUniversalTime();
                                var seca = long.Parse(keyValue.ValueData);
                                if (seca > 0)
                                {
                                    driverTimeStamp = DateTimeOffset.FromUnixTimeSeconds(seca).ToUniversalTime();
                                }
                                break;

                            case "DriverType":
                                driverType = keyValue.ValueData;
                                break;

                            case "DriverVersion":
                                driverVersion = keyValue.ValueData;
                                break;

                            case "ImageSize":
                                imageSize = int.Parse(keyValue.ValueData);
                                break;

                            case "Inf":
                                inf = keyValue.ValueData;
                                break;

                            case "Product":
                                product = keyValue.ValueData;
                                break;

                            case "ProductVersion":
                                productVersion = keyValue.ValueData;
                                break;

                            case "Service":
                                service = keyValue.ValueData;
                                break;

                            case "WdfVersion":
                                wdfVersion = keyValue.ValueData;
                                break;

                            default:
                                _logger.Warn(
                                    $"Unknown value name when processing DriverBinary at path '{binKey.KeyPath}': {keyValue.ValueName}");
                                break;
                            }
                        }

                        var db = new DriverBinary(binKey.KeyName, binaryKey.LastWriteTime.Value, driverCheckSum,
                                                  driverCompany, driverId, driverInBox, driverIsKernelMode, driverLastWriteTime, driverName,
                                                  driverPackageStrongName, driverSigned, driverTimeStamp, driverType, driverVersion,
                                                  imageSize, inf, product, productVersion, service, wdfVersion);

                        DriveBinaries.Add(db);
                    }
                    catch (Exception ex)
                    {
                        _logger.Error($"Error parsing DriverBinary at {binaryKey.KeyPath}. Error: {ex.Message}");
                        _logger.Error(
                            $"Please send the following text to [email protected]. \r\n\r\nKey data: {binaryKey}");
                    }
                }
            }


            var packaheKey = reg.GetKey(@"Root\InventoryDriverPackage");

            if (packaheKey != null)
            {
                foreach (var packKey in packaheKey.SubKeys)
                {
                    var            Class        = string.Empty;
                    var            ClassGuid    = string.Empty;
                    DateTimeOffset?Date         = null;
                    var            Directory    = string.Empty;
                    var            DriverInBox  = false;
                    var            Hwids        = string.Empty;
                    var            Inf          = string.Empty;
                    var            Provider     = string.Empty;
                    var            SubmissionId = string.Empty;
                    var            SYSFILE      = string.Empty;
                    var            Version      = string.Empty;


                    try
                    {
                        foreach (var keyValue in packKey.Values)
                        {
                            switch (keyValue.ValueName)
                            {
                            case "Class":
                                Class = keyValue.ValueData;
                                break;

                            case "ClassGuid":
                                ClassGuid = keyValue.ValueData;
                                break;

                            case "Date":
                                if (keyValue.ValueData.Length > 0)
                                {
                                    var d = new DateTimeOffset(DateTime.Parse(keyValue.ValueData).Ticks,
                                                               TimeSpan.Zero);
                                    Date = d;
                                }

                                break;

                            case "Directory":
                                Directory = keyValue.ValueData;
                                break;

                            case "DriverInBox":
                                DriverInBox = keyValue.ValueData == "1";
                                break;

                            case "Hwids":
                                Hwids = keyValue.ValueData;
                                break;

                            case "Inf":
                                Inf = keyValue.ValueData;
                                break;

                            case "Provider":
                                Provider = keyValue.ValueData;
                                break;

                            case "SubmissionId":
                                SubmissionId = keyValue.ValueData;
                                break;

                            case "SYSFILE":
                                SYSFILE = keyValue.ValueData;
                                break;

                            case "Version":
                                Version = keyValue.ValueData;
                                break;

                            default:
                                _logger.Warn(
                                    $"Unknown value name when processing DriverPackage at path '{packKey.KeyPath}': {keyValue.ValueName}");
                                break;
                            }
                        }

                        var dp = new DriverPackage(packKey.KeyName, packaheKey.LastWriteTime.Value, Class, ClassGuid,
                                                   Date, Directory, DriverInBox, Hwids, Inf, Provider, SubmissionId, SYSFILE, Version);

                        DriverPackages.Add(dp);
                    }
                    catch (Exception ex)
                    {
                        _logger.Error($"Error parsing DriverPackage at {packaheKey.KeyPath}. Error: {ex.Message}");
                        _logger.Error(
                            $"Please send the following text to [email protected]. \r\n\r\nKey data: {packaheKey}");
                    }
                }
            }
        }