void DriverUpdate(object sender, DoWorkEventArgs e)
        {
            bDriverUpdateIsGoingOn = true;
            devicesForUpdate = DevicesForScanning.Where(d => d.NeedsUpdate && d.SelectedForUpdate).ToList();

            DriverData[] scanData = new DriverData[devicesForUpdate.Count];
            DriverData[] updateData = new DriverData[devicesForUpdate.Count];

            int i = 0;
            int id;

            foreach (DeviceInfo di in devicesForUpdate)
            {
                if (Int32.TryParse(di.Id, out id))
                {
                    scanData[i] = driverData[id];
                    updateData[i] = UserUpdates[id];
                    i++;
                }
            }

            UpdateDrivers(scanData, updateData);

            scanData = null;
            updateData = null;
        }
        /// <summary>
        /// call to SDK for driver update function
        /// </summary>
        /// <param name="arrUserDrivers"></param>
        /// <param name="arrUserUpdates"></param>
        public int UpdateDrivers(DriverData[] arrUserDrivers, DriverData[] arrUserUpdates)
        {
            //bDriverUpdateIsGoingOn = true;
            int retval = 0;
            IntPtr pUnmanagedUserDrivers = IntPtr.Zero;
            IntPtr pUnmanagedUserUpdates = IntPtr.Zero;

            try
            {
                // marshal input
                pUnmanagedUserDrivers = MarshalHelper.MarshalArray(ref arrUserDrivers);
                pUnmanagedUserUpdates = MarshalHelper.MarshalArray(ref arrUserUpdates);

                // call driver update function
                retval = DUSDKHandler.updateDeviceDriversEx(
                    progressCallback,
                    szProductKey,
                    szAppDataLoc,
                    szTempLoc,
                    szRegistryLoc,
                    downloadProgressCallback,
                    pUnmanagedUserDrivers,
                    pUnmanagedUserUpdates,
                    arrUserDrivers.Length,
                    szRestorePointName
                    );

                if (retval == DUSDKHandler.DefineConstants.SUCCESS)
                {
                    //this.UIThread(() => this.label3.Text = "Drivers Updated Successfully!!");
                }
                else if (retval == DUSDKHandler.DefineConstants.CANCEL_INSTALL)
                {
                    //this.UIThread(() => this.label3.Text = "Update Stopped Successfully!!");
                }
                else if (retval == DUSDKHandler.DefineConstants.FAIL)
                {
                    if (CurrentDispatcher.Thread != null)
                    {
                        CurrentDispatcher.BeginInvoke((Action)(() =>
                        {
                            ScanStatusTitle = WPFLocalizeExtensionHelpers.GetUIString("UpdateFailed");
                            ScanStatusText = string.Empty;
                        }));
                    }
                }
                else
                {
                    ; // check for error code
                }

            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.ToString());
                //TODO: Add SmartAssembly bug tracking here!
            }
            finally
            {
                // free memory
                if (pUnmanagedUserDrivers != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pUnmanagedUserDrivers);
                }

                if (pUnmanagedUserUpdates != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pUnmanagedUserUpdates);
                }

                pUnmanagedUserDrivers = IntPtr.Zero;
                pUnmanagedUserUpdates = IntPtr.Zero;

                bDriverUpdateIsGoingOn = false;
            }

            return retval;
        }
        /// <summary>
        /// call to SDK for driver update function
        /// </summary>
        /// <param name="arrUserDrivers"></param>
        /// <param name="arrUserUpdates"></param>
        public int UpdateDrivers(DriverData[] arrUserDrivers, DriverData[] arrUserUpdates, int nOsId, DUSDKHandler.UPDATE_FLAGS updateFlag, string archivePath)
        {
            int retval = 0;
            IntPtr pUnmanagedUserDrivers = IntPtr.Zero;
            IntPtr pUnmanagedUserUpdates = IntPtr.Zero;

            try
            {
                if (arrUserDrivers != null)
                {
                    // marshal input
                    pUnmanagedUserDrivers = MarshalHelper.MarshalArray(ref arrUserDrivers);
                }

                if (arrUserUpdates != null)
                {
                    pUnmanagedUserUpdates = MarshalHelper.MarshalArray(ref arrUserUpdates);
                }

                int arrLen = 0;

                if (arrUserDrivers != null)
                {
                    arrLen = arrUserDrivers.Length;
                }

                if ((updateFlag & DUSDKHandler.UPDATE_FLAGS.UPDATE_FLAG_RESTORE_ARCHIVE_ONLY) == DUSDKHandler.UPDATE_FLAGS.UPDATE_FLAG_RESTORE_ARCHIVE_ONLY)
                {
                    // call driver update function
                    retval = DUSDKHandler.OSMT_updateDeviceDriversEx(
                        progressCallback,
                        szProductKey,
                        szAppDataLoc,
                        szTempLoc,
                        szRegistryLoc,
                        downloadProgressCallback,
                        pUnmanagedUserDrivers,
                        pUnmanagedUserUpdates,
                        arrLen,
                        szRestorePointName,
                        nOsId,
                        (uint)updateFlag,
                        new StringBuilder(archivePath)
                        );
                }
                else
                {
                    if (nOsId == -1)
                    {
                        // call driver update function
                        retval = DUSDKHandler.updateDeviceDriversEx(
                            progressCallback,
                            szProductKey,
                            szAppDataLoc,
                            szTempLoc,
                            szRegistryLoc,
                            downloadProgressCallback,
                            pUnmanagedUserDrivers,
                            pUnmanagedUserUpdates,
                            arrLen,
                            szRestorePointName
                            );
                    }
                    else
                    {
                        // call driver update function
                        retval = DUSDKHandler.OSMT_updateDeviceDriversEx(
                            progressCallback,
                            szProductKey,
                            szAppDataLoc,
                            szTempLoc,
                            szRegistryLoc,
                            downloadProgressCallback,
                            pUnmanagedUserDrivers,
                            pUnmanagedUserUpdates,
                            arrLen,
                            szRestorePointName,
                            nOsId,
                            (uint)updateFlag,
                            new StringBuilder(archivePath)
                            );
                    }
                }

                if (retval == DUSDKHandler.DefineConstants.SUCCESS)
                {
                }
                else if (retval == DUSDKHandler.DefineConstants.CANCEL_INSTALL)
                {
                }
                else if (retval == DUSDKHandler.DefineConstants.FAIL)
                {
                    if (CurrentDispatcher.Thread != null)
                    {
                        CurrentDispatcher.BeginInvoke((Action)(() =>
                        {
                            ScanStatusTitle = WPFLocalizeExtensionHelpers.GetUIString("UpdateFailed");
                            ScanStatusText = string.Empty;
                        }));
                    }
                }
                else
                {
                    ; // check for error code
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString());
                System.Diagnostics.Trace.WriteLine(ex.ToString());
            }
            finally
            {
                // free memory
                if (pUnmanagedUserDrivers != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pUnmanagedUserDrivers);
                }

                if (pUnmanagedUserUpdates != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pUnmanagedUserUpdates);
                }

                pUnmanagedUserDrivers = IntPtr.Zero;
                pUnmanagedUserUpdates = IntPtr.Zero;

                bDriverUpdateIsGoingOn = false;
            }

            return retval;
        }
        private void ComposeDrivers(object sender, DoWorkEventArgs e)
        {
            bComposingIsGoingOn = true;
            string destinationOSDriversXMLFilePath = String.Format(@"{0}\DriverData.xml", DownloadsDirectory);
            try
            {
                var xs = new XmlSerializer(typeof(DestinationOSDevices));
                using (FileStream fs = File.Create(destinationOSDriversXMLFilePath))
                {
                    xs.Serialize(fs, DestinationOSDevices);
                }
            }
            catch
            {
            }

            if (CurrentDispatcher.Thread != null)
            {
                CurrentDispatcher.BeginInvoke((Action)(() =>
                {
                    Progress = 50;
                }));
            }

            try
            {
                DriverData[] scanData = new DriverData[DevicesForDestinationOS.Count];
                DriverData[] updateData = new DriverData[DevicesForDestinationOS.Count];

                int i = 0;
                int id;

                foreach (MigrationDeviceInfo di in DevicesForDestinationOS)
                {
                    if (Int32.TryParse(di.Id, out id))
                    {
                        scanData[i] = driverData[id];
                        updateData[i] = UserUpdates[id];
                        i++;
                    }
                }

                DestinationDirectory = String.Format(@"{0}\FreeDriverScout.OSMigrationTool.Restore\", DestinationDirectory);
                Directory.CreateDirectory(DestinationDirectory);
                string archivePath = DestinationDirectory + "\\DriverData.zip";
                int retval = UpdateDrivers(scanData, updateData, nComboOsId, DUSDKHandler.UPDATE_FLAGS.UPDATE_FLAG_ARCHIVE_DOWNLOADS_ONLY, archivePath);
                if (retval == DUSDKHandler.DefineConstants.SUCCESS)
                {
                    //Adding DriverData.xml file
                    ZipFile zip = new ZipFile(archivePath);
                    zip.AddFile(destinationOSDriversXMLFilePath, @"\");
                    zip.Save();
                }
                scanData = null;
                updateData = null;
            }
            catch { }
            finally
            {
                bComposingIsGoingOn = false;
            }
        }
        void DriverDownload(object sender, DoWorkEventArgs e)
        {
            bDriverUpdateIsGoingOn = true;

            //string driverDownloadingDirectory = "";
            string clearedDeviceName = DevicesForDestinationOS[driverIndex].DeviceName.Replace(" ", "").Replace(@"/", "");

            // Delete all previously downloaded drivers
            try
            {
                Directory.Delete(DownloadsDirectory, true);
            }
            catch { }

            DestinationOSDevices.OS = nComboOsId;//DestinationOS.Key.ToString();
            DestinationOSDevices.DownloadedDestinationOSDrivers = new List<DestinationOSDeviceInfo>();

            DriverData[] scanData = new DriverData[DevicesForDestinationOS.Count];
            DriverData[] updateData = new DriverData[DevicesForDestinationOS.Count];

            int i = 0;
            int id;

            foreach (MigrationDeviceInfo di in DevicesForDestinationOS)
            {
                if (Int32.TryParse(di.Id, out id))
                {
                    scanData[i] = driverData[id];
                    updateData[i] = UserUpdates[id];
                    i++;
                }
            }

            UpdateDrivers(scanData, updateData, nComboOsId, DUSDKHandler.UPDATE_FLAGS.UPDATE_FLAG_DOWNLOAD_ONLY, null);

            scanData = null;
            updateData = null;
        }