private void DownloadFiles()
        {
            if (_downloadUrls.Any())
            {
                KeyValuePair <HPDriverPackage, Uri> data = _downloadUrls.Dequeue();

                HPDriverPackage package = data.Key;

                Uri    url      = data.Value;
                string filename = Path.GetFileName(url.LocalPath);

                currentDownloadFileName = Path.Combine(tempFolderPath, filename);
                currentModel            = package.Model;
                currentPackage          = package;

                // check if file already exists and is the same size as the one that will be downloaded
                if (File.Exists(currentDownloadFileName))
                {
                    long fileSize = new FileInfo(currentDownloadFileName).Length;
                    long webSize  = Utility.GetFileSize(url);

                    if (fileSize == webSize)
                    {
                        _extractFiles.Enqueue(new KeyValuePair <HPDriverPackage, string>(package, currentDownloadFileName));

                        CheckDownloadQueueCompleted();

                        return;
                    }
                }

                // enable https downloads
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

                webClient = new WebClient();
                webClient.DownloadProgressChanged += Client_DownloadProgressChanged;
                webClient.DownloadFileCompleted   += Client_DownloadFileCompleted;
                webClient.DownloadFileAsync(url, currentDownloadFileName);

                return;
            }
        }
        private void ExtractFiles()
        {
            if (_extractFiles.Any())
            {
                KeyValuePair <HPDriverPackage, string> data = _extractFiles.Dequeue();

                // add model so we can re-use it in functions
                HPDriverPackage package = data.Key;
                currentModel = package.Model;

                // update my best friend the progress bar
                backgroundWorker.ReportProgress(Convert.ToInt32(50 + ((50 / totalPacks * extracted) * 0.5)), string.Format("Processing {0} : extracting to temp folder", currentModel));
                // generate model folder name

                // hp sp extract does not work directly to network share, put in temp folder first and than copy to share
                string tempFolder        = Path.Combine(tempFolderPath, "extract", package.FolderName);
                string destinationFolder = Path.Combine(sourceFolderPath, package.FolderName);

                using (extractProcess = new Process())
                {
                    try
                    {
                        // Start a process to print a file and raise an event when done.
                        extractProcess.StartInfo.FileName        = data.Value;
                        extractProcess.StartInfo.Arguments       = string.Format("-pdf -f \"{0}\" -s -e", tempFolder);
                        extractProcess.StartInfo.CreateNoWindow  = true;
                        extractProcess.StartInfo.UseShellExecute = true;
                        extractProcess.StartInfo.Verb            = "RunAs";
                        extractProcess.Start();
                        extractProcess.WaitForExit();
                        extractProcess.Close();

                        // update my best friend the progress bar
                        backgroundWorker.ReportProgress(Convert.ToInt32(50 + ((100 / totalPacks * extracted) * 0.5) - 1), string.Format("Processing {0} : moving to destination folder", currentModel));

                        if (!Directory.Exists(tempFolder))
                        {
                            throw new DirectoryNotFoundException("Temp folder not found " + tempFolder);
                        }

                        // add a version file to the folder so we can check later if there is an update to the download
                        string versionFile = Path.Combine(tempFolderPath, "extract", package.FolderName, package.VersionFile);
                        File.Create(versionFile).Close();

                        // wipe old soruce folder
                        if (registry.ReadBool("WipeSource") && Directory.Exists(destinationFolder))
                        {
                            Directory.Delete(destinationFolder, true);
                        }

                        // remove old version file
                        if (Directory.Exists(destinationFolder))
                        {
                            string[] fileList = Directory.GetFiles(destinationFolder, "*.version");
                            foreach (string file in fileList)
                            {
                                File.Delete(file);
                            }
                        }

                        Utility.Copy(tempFolder, destinationFolder, true);

                        Directory.Delete(tempFolder, true);
                    }
                    catch (Exception ex)
                    {
                        error.Add(currentModel, "Cannot extract driver pack: " + ex.Message);

                        CheckExtractQueueCompleted();

                        return;
                    }
                }

                successful.Add(currentModel);

                CheckExtractQueueCompleted();

                return;
            }
        }
        private void ProcessCatalog()
        {
            dataGridViewDriverPackages.Rows.Clear();

            bool   known  = false;
            string prefix = string.IsNullOrEmpty(registry.ReadString("HPFolderPrefix")) ? "HP" : registry.ReadString("HPFolderPrefix");

            string tempFile = Path.Combine(Path.GetTempPath(), "HPClientDriverPackCatalog.cab");

            using (FileStream innerCab = new FileStream(tempFile, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                CabEngine engine = new CabEngine();
                foreach (ArchiveFileInfo archiveFileInfo in engine.GetFileInfo(innerCab))
                {
                    using (Stream stream = engine.Unpack(innerCab, archiveFileInfo.Name))
                    {
                        catalog = XElement.Load(stream);

                        IEnumerable <XElement> nodeList = catalog.Element("HPClientDriverPackCatalog").Element("ProductOSDriverPackList").Elements("ProductOSDriverPack").Where(
                            x => x.Element("OSName").Value == UserData["OS"].ToString()
                            );
                        foreach (XElement node in nodeList)
                        {
                            HPDriverPackage package = new HPDriverPackage(node)
                            {
                                SoftPaq = catalog.Element("HPClientDriverPackCatalog").Element("SoftPaqList").Elements("SoftPaq").Where(
                                    x => x.Element("Id").Value == node.Element("SoftPaqId").Value
                                    ).FirstOrDefault(),
                                Vendor = prefix
                            };
                            package.ProcessSoftPaq();
                            package.GenerateModelFolderName(os, structure);

                            DataGridViewRow dataGridViewRow = new DataGridViewRow();
                            dataGridViewRow.CreateCells(dataGridViewDriverPackages);

                            dataGridViewRow.Cells[0].Value = false;
                            dataGridViewRow.Cells[1].Value = package.Model;
                            dataGridViewRow.Cells[2].Value = package.VersionShort;
                            dataGridViewRow.Cells[3].Value = package.Size.ToString();

                            dataGridViewRow.Tag = package;
                            dataGridViewDriverPackages.Rows.Add(dataGridViewRow);
                        }
                    }
                }
            }

            // TODO: will implement when I have an HP device to test with
            //string query = "SELECT DISTINCT Model FROM SMS_G_System_COMPUTER_SYSTEM WHERE Manufacturer = 'HP' OR Manufacturer = 'Hewlett-Packard'";
            //List<IResultObject> models = Utility.SearchWMIToList(ConnectionManager, query);

            //foreach (IResultObject model in models)
            //{
            //    string testModel = model["Model"].StringValue;
            //    testModel = Regex.Replace(testModel, "HP", "", RegexOptions.IgnoreCase);
            //    testModel = Regex.Replace(testModel, "COMPAQ", "", RegexOptions.IgnoreCase);
            //    testModel = Regex.Replace(testModel, "SFF", "Small Form Factor");
            //    testModel = Regex.Replace(testModel, "USDT", "Desktop");
            //    testModel = Regex.Replace(testModel, " TWR", " Tower");
            //    testModel = testModel.TrimEnd("PC").Trim();

            //    DataGridViewRow row = dataGridViewDriverPackages.Rows
            //        .Cast<DataGridViewRow>()
            //        .Where(r => r.Cells[1].Value.ToString().Equals(testModel, StringComparison.CurrentCultureIgnoreCase))
            //        .FirstOrDefault();

            //    if (row != null)
            //    {
            //        row.Cells[0].Value = true;
            //        row.Cells[4].Value = "Model detected";
            //        known = true;
            //    }
            //}

            foreach (DataGridViewRow dataGridViewRow in dataGridViewDriverPackages.Rows)
            {
                HPDriverPackage package = (HPDriverPackage)dataGridViewRow.Tag;

                string path = Path.Combine(sourceFolderPath, package.FolderName);

                if (Directory.Exists(path))
                {
                    string[] fileList = Directory.GetFiles(path, "*.version");
                    if (File.Exists(Path.Combine(path, package.VersionFile)))
                    {
                        dataGridViewRow.Cells[0].Value = false;
                        dataGridViewRow.Cells[4].Value = "Downloaded";
                    }
                    else if (fileList.Length > 0)
                    {
                        dataGridViewRow.Cells[0].Value = false;
                        dataGridViewRow.Cells[4].Value = "New version";
                    }
                }
            }

            dataGridViewDriverPackages.Sort(known ? columnStatus : columnPack, known ? ListSortDirection.Descending : ListSortDirection.Ascending);

            Initialized = true;
        }