Example #1
0
        internal BitsJob(IBackgroundCopyJob job)
        {
            _job = job;

            RefreshJobProperties();
            RefreshFileProperties();
        }
Example #2
0
        /// <summary>
        /// Verifies if the task has a download job assigned, meaning this is a retry.
        /// If a transferred job is detected, the job is completed and the event
        /// OnDownloadCompleted is raised.
        /// </summary>
        /// <param name="copyManager">The BITS background copy manager to use</param>
        /// <param name="task">The DownloadTask to get the data from</param>
        /// <param name="copyJob">If an in progress BITS job is found for this task, this job is returned on this parameter</param>
        /// <returns>A Boolean value indicating whether the job is completed or not.
        /// A True value means that the job has been completed by BITS while a False value
        /// means that the job doesn't exists or can be resumed.
        /// </returns>
        private bool CheckForResumeAndProceed(IBackgroundCopyManager copyManager, DownloadTask task,
                                              out IBackgroundCopyJob copyJob)
        {
            copyJob = null;
            if (task.JobId != null && task.DownloadErrorResumeCount < BackgroundDownloadManager.MaxDownloadErrorResumes)
            {
                Guid jobId = task.JobId.Value;

                try
                {
                    copyManager.GetJob(ref jobId, out copyJob);
                    if (copyJob != null)
                    {
                        BG_JOB_STATE jobState;
                        copyJob.GetState(out jobState);
                        if (jobState == BG_JOB_STATE.BG_JOB_STATE_TRANSFERRED)
                        {
                            OnJobTransferred(task, copyJob);
                            return(true);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error(
                        new DownloaderException(
                            String.Format(
                                "The BITSDownloader cannot connect to the job '{0}' for the task '{1}' so a new BITS job will be created.",
                                jobId, task.TaskId), ex));
                }
            }
            return(false);
        }
        /// <summary>
        /// Attemps to find the job with the given identifier.
        /// </summary>
        /// <param name="id">The job's identifier.</param>
        /// <returns>
        /// The job or <see langword="null" /> if not found.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">An unexpected exception occurred trying to find the given job.</exception>
        public IDownloadJob FindJob(Guid id)
        {
            IBackgroundCopyManager bitsManager = null;
            IBackgroundCopyJob     bitsJob     = null;

            try {
                bitsManager = (IBackgroundCopyManager) new BackgroundCopyManager();
                bitsManager.GetJob(ref id, out bitsJob);

                if (bitsJob != null)
                {
                    return(new DownloadJob(id, bitsJob));
                }

                return(null);
            } catch (COMException cex) {
                if ((uint)cex.ErrorCode == (uint)BG_RESULT.BG_E_NOT_FOUND)
                {
                    return(null);
                }

                string error;
                bitsManager.GetErrorDescription(cex.ErrorCode, 1033, out error);
                throw new InvalidOperationException(error, cex);
            } finally {
                if (bitsJob != null)
                {
                    Marshal.ReleaseComObject(bitsJob);
                }
                if (bitsManager != null)
                {
                    Marshal.ReleaseComObject(bitsManager);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Prepares a BITS job adding the files and creating the required folders.
        /// </summary>
        /// <param name="backgroundCopyJob">The BITS job information.</param>
        /// <param name="task">The DownloadTask instace.</param>
        private static void PrepareJob(IBackgroundCopyJob backgroundCopyJob, DownloadTask task)
        {
            Guid jobID;

            backgroundCopyJob.GetId(out jobID);
            task.JobId = jobID;

            DownloadFile sourceFile = task.DownloadItem.File;
            string       src        = sourceFile.Source;

            //  to defend against config errors, check to see if the path given is UNC;
            //  if so, throw immediately there's a misconfiguration.  Paths to BITS must be HTTP or HTTPS
            if (FileHelper.IsUncPath(src))
            {
                Exception ex = new DownloaderException("Download location must be HTTP or HTTPS URL");
                Logger.Error(ex);
                throw ex;
            }

            //TODO: how about duplicate filenames?
            string dest = Path.Combine(task.DownloadFilesBase, sourceFile.LocalName);

            if (!Directory.Exists(Path.GetDirectoryName(dest)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(dest));
            }

            //  add this file to the job
            backgroundCopyJob.AddFile(src, dest);
        }
        private void BitsAction(Action <IBackgroundCopyJob> action)
        {
            IBackgroundCopyManager bitsManager = null;
            IBackgroundCopyJob     bitsJob     = null;

            try {
                bitsManager = (IBackgroundCopyManager) new BackgroundCopyManager();
                bitsManager.GetJob(ref id, out bitsJob);
                if (bitsJob != null)
                {
                    action(bitsJob);
                }
            } catch (COMException cex) {
                string error;
                bitsManager.GetErrorDescription(cex.ErrorCode, 1033, out error);
                throw new InvalidOperationException(error, cex);
            } finally {
                if (bitsJob != null)
                {
                    Marshal.ReleaseComObject(bitsJob);
                }
                if (bitsManager != null)
                {
                    Marshal.ReleaseComObject(bitsManager);
                }
            }
        }
Example #6
0
        internal static BackgroundCopyJobState GetState(IBackgroundCopyJob ijob)
        {
            BackgroundCopyJobState o;

            ijob.GetState(out o);
            return(o);
        }
        void IBackgroundCopyCallback.JobError(IBackgroundCopyJob bitsJob, IBackgroundCopyError error)
        {
            try {
                // if the error hasn't been reported, try to get it
                if (error == null)
                {
                    bitsJob.GetError(out error);
                }
            } catch (COMException) { }

            // If we've got the native error, extract values and populate the
            // status message.
            if (error != null)
            {
                StatusMessage = FormatError(error);
            }

            BG_JOB_STATE state;

            bitsJob.GetState(out state);
            if (state != BG_JOB_STATE.BG_JOB_STATE_ACKNOWLEDGED &&
                state != BG_JOB_STATE.BG_JOB_STATE_CANCELLED)
            {
                bitsJob.Cancel();
            }

            Status = DownloadStatus.Error;
        }
Example #8
0
 internal BitsJob(BitsManager manager, IBackgroundCopyJob job)
 {
     this.manager = manager;
     this.job     = job;
     this.job2    = this.job as IBackgroundCopyJob2;
     this.NotificationInterface = manager.NotificationHandler;
 }
Example #9
0
        public void JobModification(IBackgroundCopyJob pJob, uint dwReserved)
        {
            BitsJob job;

            if (null != this.onJobModified)
            {
                Guid guid;
                pJob.GetId(out guid);
                if (manager.Jobs.ContainsKey(guid))
                {
                    job = manager.Jobs[guid];
                }
                else
                {
                    // Update Joblist to check whether the job still exists. If not, just return
                    manager.EnumJobs(manager.currentOwner);
                    if (manager.Jobs.ContainsKey(guid))
                    {
                        job = manager.Jobs[guid];
                    }
                    else
                    {
                        return;
                    }
                }
                this.onJobModified(this, new NotificationEventArgs(job));
                //forward event
                if (job.notificationTarget != null)
                {
                    job.notificationTarget.JobModification(pJob, dwReserved);
                }
            }
        }
        internal DownloadJob(Guid id, IBackgroundCopyJob bitsJob)
        {
            this.id = id;

            string name;

            bitsJob.GetDisplayName(out name);
            DisplayName = name;

            string description;

            bitsJob.GetDescription(out description);
            Description = description;

            BG_JOB_PRIORITY priority;

            bitsJob.GetPriority(out priority);
            Priority = (DownloadPriority)(int)priority;

            bitsJob.GetMinimumRetryDelay(out minimumRetryDelay);
            bitsJob.GetNoProgressTimeout(out noProgressTimeout);

            BG_JOB_STATE state;

            bitsJob.GetState(out state);
            Status = (DownloadStatus)(int)state;

            _BG_JOB_PROGRESS progress;

            bitsJob.GetProgress(out progress);
            BytesTotal       = progress.BytesTotal;
            BytesTransferred = progress.BytesTransferred;

            bitsJob.SetNotifyInterface(this);

            IEnumBackgroundCopyFiles enumFiles = null;

            try {
                bitsJob.EnumFiles(out enumFiles);
                uint fetched;
                IBackgroundCopyFile file;
                enumFiles.Next(1, out file, out fetched);
                if (fetched == 1)
                {
                    string remoteUrl;
                    file.GetRemoteName(out remoteUrl);
                    RemoteUrl = remoteUrl;

                    string localName;
                    file.GetLocalName(out localName);
                    LocalFile = localName;
                }
            } finally {
                if (enumFiles != null)
                {
                    Marshal.ReleaseComObject(enumFiles);
                }
            }
        }
 void IBackgroundCopyCallback.JobModification( IBackgroundCopyJob pJob, uint dwReserved )
 {
     EventHandler<EventArgs<BitsJob>> handler = JobModification;
     if ( handler != null )
     {
         handler( this, new EventArgs<BitsJob>( new BitsJob( new BitsJobAdapter( pJob ) ) ) );
     }
 }
 void IBackgroundCopyCallback.JobTransferred( IBackgroundCopyJob pJob )
 {
     EventHandler<EventArgs<BitsJob>> handler = JobTransferred;
     if ( handler != null )
     {
         handler( this, new EventArgs<BitsJob>( new BitsJob( new BitsJobAdapter( pJob ) ) ) );
     }
 }
 /// <summary>Moves the enumerator index to the next object in the collection.</summary>
 /// <returns></returns>
 public bool MoveNext()
 {
     try
     {
         icurrentjob = ienum.Next(1)?.FirstOrDefault();
         return(icurrentjob != null);
     }
     catch { return(false); }
 }
Example #14
0
 internal BackgroundCopyJob(IBackgroundCopyJob ijob)
 {
     if (ijob == null)
     {
         throw new ArgumentNullException("IBackgroundCopyJob");
     }
     m_ijob  = ijob;
     m_files = new BackgroundCopyFileSet(ijob);
 }
Example #15
0
        /// <summary>
        /// Internal copy-job factory method.  Used to coordinate all aspects of a job set-up,
        /// which includes creating a copy manager, creating a job within it, setting download
        /// parameters, and adding the job to our tracking collection for cleanup later
        /// </summary>
        /// <param name="copyManager">null reference to copy manager</param>
        /// <param name="copyJob">null reference to copy job</param>
        /// <param name="jobID">null reference to job id guid</param>
        /// <param name="jobName">string. Job name</param>
        /// <param name="jobDesc">string. Job description</param>
        /// <param name="task">DownloadTask. Used to get infos about credentials, proxy, etc.</param>
        private void CreateCopyJob(
            IBackgroundCopyManager copyManager,
            out IBackgroundCopyJob copyJob,
            ref Guid jobID,
            string jobName,
            string jobDesc,
            DownloadTask task)
        {
            // create the job, set its description, use "out" semantics to get jobid and the actual job object
            copyManager.CreateJob(
                jobName,
                BG_JOB_TYPE.BG_JOB_TYPE_DOWNLOAD,
                out jobID,
                out copyJob);

            //  set useful description
            copyJob.SetDescription(jobDesc);

            //  ***
            //      SET UP BITS JOB SETTINGS--TIMEOUTS/RETRY ETC
            //      SEE THE FOLLOWING REFERENCES:
            //  **  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/IBackgroundCopyJob2_setminimumretrydelay.asp?frame=true
            //  **  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/IBackgroundCopyJob2_setnoprogresstimeout.asp?frame=true
            //  **  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/bg_job_priority.asp
            //  ***

            //  in constant set to 0; this makes BITS retry as soon as possible after an error
            copyJob.SetMinimumRetryDelay(BitsMinimumRetryDelay);
            //  in constant set to 5 seconds; BITS will set job to Error status if exceeded
            copyJob.SetNoProgressTimeout(BitsNoProgressTimeout);
            //  make this job the highest (but still background) priority--
            copyJob.SetPriority(BG_JOB_PRIORITY.BG_JOB_PRIORITY_HIGH);
            //  ***

            //----------------------------------------------------------------------
            //-- Data Management and Research, Inc. - Paul Cox - 8/13/2004
            //-- ADDED the following lines to verify credentials of file copy job
            //----------------------------------------------------------------------

            // Set credentials on the job
            VerifyAndSetBackgroundCopyJobCredentials(copyJob, task);
            // Set proxy infos (incl Proxy Auth.)
            VerifyAndSetBackgroundCopyJobProxy(copyJob, task);

            //----------------------------------------------------------------------
            //-- End ADDED
            //----------------------------------------------------------------------

            //  lock our internal collection of jobs, and add this job--we use this collection in Dispose()
            //  to tell BITS to Cancel() jobs--and remove them from the queue
            //  if we did not do this, BITS would continue for (by default) two weeks to download what we asked!
            lock (bitsDownloaderJobs.SyncRoot)
            {
                bitsDownloaderJobs.Add(jobID, jobName);
            }
        }
Example #16
0
 /// <summary>
 /// Disposes of the BackgroundCopyJob object.
 /// </summary>
 public void Dispose()
 {
     try
     {
         this.NotifyFlags = 0;
         m_ijob.SetNotifyInterface(null);
     }
     catch { }
     m_files = null;  m_ijob = null; m_ijob2 = null; m_ijob3 = null; m_notifier = null;
 }
 void IBackgroundCopyCallback.JobError( IBackgroundCopyJob pJob, IBackgroundCopyError pError )
 {
     EventHandler<JobErrorEventArgs> handler = JobError;
     if ( handler != null )
     {
         handler( this,
                  new JobErrorEventArgs( new BitsJob( new BitsJobAdapter( pJob ) ),
                                         new BitsError( new BitsErrorAdapter( pError ) ) ) );
     }
 }
Example #18
0
        internal BitsJob(IBackgroundCopyJob job)
        {
            if (job == null)
            {
                throw new ArgumentNullException("job");
            }

            _job = job;

            _progressWatch = new BitsProgressWatch(this);
        }
Example #19
0
        /// <summary>
        /// Centralizes all chores related to stopping and cancelling a copy job, and getting back
        /// from BITS the errors incurred during the job.
        /// </summary>
        /// <param name="task">reference to the job associated task</param>
        /// <param name="pJob">reference to the copy job object (not job id)</param>
        /// <param name="pError">reference to the COM error reported by bits (might be null)</param>
        /// <param name="ex">reference to an exception cosidered as an error (might be null)</param>
        private void OnJobError(DownloadTask task, IBackgroundCopyJob pJob, IBackgroundCopyError pError, Exception ex)
        {
            Exception finalException = ex;

            if (pJob != null)
            {
                //  get information about this job
                string jobDesc;
                pJob.GetDescription(out jobDesc);
                string jobName;
                pJob.GetDisplayName(out jobName);
                Guid jobID;
                pJob.GetId(out jobID);

                try
                {
                    // if the error hasn't been reported, try to get it
                    if (pError == null)
                    {
                        pJob.GetError(out pError);
                    }
                }
                catch (COMException e)
                {
                    Logger.Error(e);
                    if (e.ErrorCode != ExceptionCodeNotAnError)
                    {
                        throw;
                    }
                }

                // If we've got the native error, wrap into a nicer exception
                if (pError != null)
                {
                    var BitsEx = new BitsDownloadErrorException(pError, (uint)CultureIdForGettingComErrorMessages);
                    cumulativeErrorMessage += BitsEx.Message + Environment.NewLine;
                    finalException          = BitsEx;
                }


                BG_JOB_STATE state;
                pJob.GetState(out state);
                if (state != BG_JOB_STATE.BG_JOB_STATE_ACKNOWLEDGED &&
                    state != BG_JOB_STATE.BG_JOB_STATE_CANCELLED)
                {
                    pJob.Cancel();
                }
                RemoveCopyJobEntry(jobID);
            }

            OnDownloadError(new DownloadTaskErrorEventArgs(task, finalException));
            Logger.Error(finalException);
            //throw finalException;
        }
Example #20
0
        /// <summary>
        /// Method called by BITS when the job is modified, this method is used to notify progress.
        /// </summary>
        /// <param name="task">The DownloadTask instance.</param>
        /// <param name="pJob">The BITS job reference.</param>
        private void OnJobModification(DownloadTask task, IBackgroundCopyJob pJob)
        {
            BG_JOB_PROGRESS progress;

            pJob.GetProgress(out progress);

            var args = new DownloadTaskProgressEventArgs((long)progress.BytesTotal,
                                                         (long)progress.BytesTransferred, (int)progress.FilesTotal,
                                                         (int)progress.FilesTransferred, task);

            OnDownloadProgress(args);
        }
Example #21
0
 protected virtual void Dispose(bool disposing)
 {
     if (!this.disposed)
     {
         if (disposing)
         {
             //TODO: release COM resource
             this.job = null;
         }
     }
     disposed = true;
 }
Example #22
0
        /// <summary>
        /// Synchronous download method implementation.
        /// </summary>
        /// <param name="task">The DownloadTask to process.</param>
        /// <param name="maxWaitTime">The maximum wait time.</param>
        public void Download(DownloadTask task, TimeSpan maxWaitTime)
        {
            IBackgroundCopyManager backGroundCopyManager = null;
            IBackgroundCopyJob     backgroundCopyJob     = null;
            Guid jobID = Guid.Empty;

            try
            {
                //  create the manager
                backGroundCopyManager = (IBackgroundCopyManager) new BackgroundCopyManager();

                // If the job is already finished, just return
                if (CheckForResumeAndProceed(backGroundCopyManager, task, out backgroundCopyJob))
                {
                    return;
                }

                if (backgroundCopyJob == null)
                {
                    //  use utility function to create manager, job, get back jobid etc.; uses 'out' semantics
                    CreateCopyJob(
                        backGroundCopyManager,
                        out backgroundCopyJob,
                        ref jobID,
                        task.DownloadItem.OwnerItemId,
                        task.DownloadItem.Enclosure.Description, task);

                    // Save the jobId in the task
                    task.JobId = jobID;

                    // Prepare the job to download the manifest files
                    PrepareJob(backgroundCopyJob, task);
                }

                WaitForDownload(task, backgroundCopyJob, maxWaitTime);
            }
            catch (Exception e)
            {
                //  if exception, clean up job
                OnJobError(task, backgroundCopyJob, null, e);
            }
            finally
            {
                if (null != backgroundCopyJob)
                {
                    Marshal.ReleaseComObject(backgroundCopyJob);
                }
                if (null != backGroundCopyManager)
                {
                    Marshal.ReleaseComObject(backGroundCopyManager);
                }
            }
        }
Example #23
0
        /// <summary>Called when an error occurs.</summary>
        /// <param name="copyJob">Contains job-related information, such as the number of bytes and files transferred before the error occurred. It also contains the methods to resume and cancel the job. Do not release pJob; BITS releases the interface when the JobError method returns.</param>
        /// <param name="error">Contains error information, such as the file being processed at the time the fatal error occurred and a description of the error. Do not release pError; BITS releases the interface when the JobError method returns.</param>
        public void JobError(IBackgroundCopyJob copyJob, IBackgroundCopyError error)
        {
            if (this.manager == null)
            {
                return;
            }

            BitsJob job;

            if (null == this.errorOccurred)
            {
                return;
            }

            Guid guid;

            copyJob.GetId(out guid);
            if (this.manager.Jobs.ContainsKey(guid))
            {
                job = this.manager.Jobs[guid];
            }
            else
            {
                // Update Job list to check whether the job still exists. If not, just return
                this.manager.EnumJobs(this.manager.CurrentOwner);
                if (this.manager.Jobs.ContainsKey(guid))
                {
                    job = this.manager.Jobs[guid];
                }
                else
                {
                    return;
                }
            }

            this.errorOccurred(this, new ErrorNotificationEventArgs(job, new BitsError(job, error)));

            // forward event
            if (job.NotificationTarget == null)
            {
            }
            else
            {
                try
                {
                    job.NotificationTarget.JobError(copyJob, error);
                }
                catch (COMException)
                {
                }
            }
        }
Example #24
0
 internal BitsJob(BitsManager manager, IBackgroundCopyJob job)
 {
     this.manager = manager;
     this.job = job;
     this.job2 = this.job as IBackgroundCopyJob2;
     ///store existing notification handler and route message to this as well
     ///otherwisse it may break system download jobs
     if (this.NotificationInterface != null)
     {
         this.notificationTarget = this.NotificationInterface;   //pointer to the existing one;
     }
     this.NotificationInterface = manager.NotificationHandler;
 }
        void IBackgroundCopyCallback.JobModification(IBackgroundCopyJob bitsJob, uint reserved)
        {
            _BG_JOB_PROGRESS progress;

            bitsJob.GetProgress(out progress);
            BytesTotal       = progress.BytesTotal;
            BytesTransferred = progress.BytesTransferred;

            BG_JOB_STATE state;

            bitsJob.GetState(out state);
            Status = (DownloadStatus)(int)state;
        }
Example #26
0
        /// <summary>
        /// Centralizes all chores related to stopping and cancelling a copy job, and getting back
        /// from BITS the errors incurred during the job.
        /// </summary>
        /// <param name="copyJob">reference to the copy job object (not job id)</param>
        /// <param name="errMessage">a cumulative error message passed by reference so
        /// that additions can be made</param>
        private void HandleDownloadErrorCancelJob(
            IBackgroundCopyJob copyJob,
            ref string errMessage)
        {
            string singleError             = "";
            string jobDesc                 = "";
            string jobName                 = "";
            Guid   jobID                   = Guid.Empty;
            IBackgroundCopyError copyError = null;

            try
            {
                //  check if job is null; don't try to clean up null references!
                if (null != copyJob)
                {
                    //  get information about this job for reporting the error
                    copyJob.GetDescription(out jobDesc);
                    copyJob.GetDisplayName(out jobName);
                    copyJob.GetId(out jobID);

                    //  find out what the error was
                    copyJob.GetError(out copyError);

                    // use the culture id specified in RESX to tell COM which culture to return err message in:
                    copyError.GetErrorDescription((uint)CULTURE_ID_FOR_COM, out singleError);

                    //  add error to our "stack" of errors:
                    errMessage += singleError + Environment.NewLine;

                    //  notify BITS that we consider this job a loss, forget about it:
                    copyJob.Cancel();

                    //  remove job from collection
                    RemoveCopyJobEntry(jobID);

                    //  log error, but don't throw here; let dnldmgr take care of error
                    //  NOTE that errMessage is used cumulatively for full track of problem
                    errMessage = ApplicationUpdateManager.TraceWrite("[BITSDownloader]", "RES_EXCEPTION_BITSBackgroundCopyError", jobID, jobName, jobDesc, errMessage);

                    ExceptionManager.Publish(new Exception(errMessage));
                }
            }
            finally
            {
                if (null != copyError)
                {
                    Marshal.ReleaseComObject(copyError);
                    copyError = null;
                }
            }
        }
Example #27
0
        /// <summary>
        /// Locate the DownloadTask associated with the given background job.
        /// </summary>
        /// <param name="pJob">The job reference.</param>
        /// <returns>The DownloadTask for that job.</returns>
        private static DownloadTask FindTask(IBackgroundCopyJob pJob)
        {
            Guid jobID;

            pJob.GetId(out jobID);

            foreach (var task in BackgroundDownloadManager.GetTasks())
            {
                if (task.JobId == jobID)
                {
                    return(task);
                }
            }

            return(null);
        }
Example #28
0
        internal BitsJob(BitsManager manager, IBackgroundCopyJob job)
        {
            this.manager = manager;
            this.job     = job;
            this.job2    = this.job as IBackgroundCopyJob2;
            this.job3    = this.job as IBackgroundCopyJob3;
            this.job4    = this.job as IBackgroundCopyJob4;

            ///store existing notification handler and route message to this as well
            ///otherwise it may break system download jobs
            if (this.NotificationInterface != null)
            {
                this.notificationTarget = this.NotificationInterface;   //pointer to the existing one;
            }
            this.NotificationInterface = manager.NotificationHandler;   //notification interface will be disabled when NotifyCmd is set
        }
Example #29
0
        /// <summary>
        /// Method responsible for checking the authentication type and setting the
        /// appropriate credentials. If the NTLM authentication is used then
        /// if the username and password are not provided then we use null values. For
        /// all other authentication schemes we need a username and password.
        /// </summary>
        /// <param name="backgroundCopyJob">BackgroundJob on which we need to set the credentials.</param>
        /// <param name="task">DownloadTask. Provides the infos about download credentials</param>
        private static void VerifyAndSetBackgroundCopyJobCredentials(IBackgroundCopyJob backgroundCopyJob, DownloadTask task)
        {
            try
            {
                var          copyJob = (IBackgroundCopyJob2)backgroundCopyJob;
                ICredentials creds   = task.DownloadItem.Credentials;
                var          uri     = new Uri(task.DownloadItem.File.Source);

                if (creds != null)
                {
                    //Specify HTTP Authentication (Basic) credentials
                    var credentials = new BG_AUTH_CREDENTIALS();
                    credentials.Credentials.Basic.UserName = creds.GetCredential(uri, "Basic").UserName;
                    credentials.Credentials.Basic.Password = creds.GetCredential(uri, "Basic").Password;
                    credentials.Scheme = BG_AUTH_SCHEME.BG_AUTH_SCHEME_BASIC;
                    credentials.Target = BG_AUTH_TARGET.BG_AUTH_TARGET_SERVER;
                    copyJob.SetCredentials(ref credentials);

                    //Specify HTTP Authentication (Digest) credentials
                    credentials = new BG_AUTH_CREDENTIALS();
                    credentials.Credentials.Basic.UserName = creds.GetCredential(uri, "Digest").UserName;
                    credentials.Credentials.Basic.Password = creds.GetCredential(uri, "Digest").Password;
                    credentials.Scheme = BG_AUTH_SCHEME.BG_AUTH_SCHEME_DIGEST;
                    credentials.Target = BG_AUTH_TARGET.BG_AUTH_TARGET_SERVER;
                    copyJob.SetCredentials(ref credentials);

                    //Specify NTLM credentials
                    credentials = new BG_AUTH_CREDENTIALS();
                    credentials.Credentials.Basic.UserName =
                        string.IsNullOrEmpty(creds.GetCredential(uri, "NTLM").Domain)
                            ?
                        creds.GetCredential(uri, "NTLM").UserName
                            :
                        creds.GetCredential(uri, "NTLM").Domain + "\\" +
                        creds.GetCredential(uri, "NTLM").UserName;
                    credentials.Credentials.Basic.Password = creds.GetCredential(uri, "NTLM").Password;
                    credentials.Scheme = BG_AUTH_SCHEME.BG_AUTH_SCHEME_NTLM;
                    credentials.Target = BG_AUTH_TARGET.BG_AUTH_TARGET_SERVER;
                    copyJob.SetCredentials(ref credentials);
                } //if(creds != null)
            }
            catch (Exception e)
            {
                Logger.Error("Error in VerifyAndSetBackgroundCopyJobCredentials():", e);
            }
        }
        //  --------------
        //  Dispose method
        //  --------------

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>

        public void Dispose()
        {
            if (interop != null)
            {
                // free unmanaged resources
                if (callback != null)
                {
                    var hr = interop.SetNotifyInterface(null);
                    if (HResult.Succeeded(hr) || hr == HResult.RPC_E_DISCONNECTED)
                    {
                        callback = null;
                    }
                }
                _       = Marshal.ReleaseComObject(interop);
                interop = null;
            }
            GC.SuppressFinalize(this);
        }
Example #31
0
        /// <summary>
        /// Supports multiple simultaneous downloads asynchronously.  Starts the job immediately and returns a GUID while the download continues.
        /// </summary>
        /// <param name="sourceFile">a string array of source files, which MUST BE URL's they cannot be UNC paths</param>
        /// <param name="destFile">a string array of destination paths which MUST BE UNC's they cannot be URL paths</param>
        /// <returns>a GUID which is a job id for future reference</returns>
        Guid IDownloader.BeginDownload(string[] sourceFile, string[] destFile)
        {
            IBackgroundCopyManager backGroundCopyManager = null;
            IBackgroundCopyJob     backGroundCopyJob     = null;
            Guid jobID = Guid.Empty;

            try
            {
                //  use utility function to create the job.
                CreateCopyJob(
                    out backGroundCopyManager,
                    out backGroundCopyJob,
                    ref jobID,
                    "RES_BITSFilesDownloadJobName",
                    "RES_BITSFilesDownloadDescription");

                // Add the file to the Job List
                for (int i = 0; i < sourceFile.Length; i++)
                {
                    //  to defend against config errors, check to see if the path given is UNC;
                    //  if so, throw immediately there's a misconfiguration.  Paths to BITS must be HTTP or HTTPS
                    ThrowIfSourceIsUNC(sourceFile[i]);

                    //  add this file to the job
                    backGroundCopyJob.AddFile(sourceFile[i], destFile[i]);
                }

                // Start the Back Ground Copy Job.
                backGroundCopyJob.Resume();

                return(jobID);
            }
            finally
            {
                if (null != backGroundCopyJob)
                {
                    Marshal.ReleaseComObject(backGroundCopyJob);
                }
                if (null != backGroundCopyManager)
                {
                    Marshal.ReleaseComObject(backGroundCopyManager);
                }
            }
        }
Example #32
0
        public void JobError(IBackgroundCopyJob pJob, IBackgroundCopyError pError)
        {
            BitsJob job;

            if (null != this.onJobErrored)
            {
                Guid guid;
                pJob.GetId(out guid);
                if (manager.Jobs.ContainsKey(guid))
                {
                    job = manager.Jobs[guid];
                }
                else
                {
                    job = new BitsJob(manager, pJob);
                }
                this.onJobErrored(this, new ErrorNotificationEventArgs(job, new BitsError(job, pError)));
            }
        }
Example #33
0
        public void JobModification(IBackgroundCopyJob pJob, uint dwReserved)
        {
            BitsJob job;

            if (null != this.onJobModified)
            {
                Guid guid;
                pJob.GetId(out guid);
                if (manager.Jobs.ContainsKey(guid))
                {
                    job = manager.Jobs[guid];
                }
                else
                {
                    job = new BitsJob(manager, pJob);
                }
                this.onJobModified(this, new NotificationEventArgs(job));
            }
        }
Example #34
0
        /// <summary>Initializes a new instance of the <see cref="BitsJob" /> class.</summary>
        /// <param name="manager">The manager for the BITS.</param>
        /// <param name="job">The current job.</param>
        internal BitsJob(BitsManager manager, IBackgroundCopyJob job)
        {
            this.manager = manager;
            this.Job = job;
            this.job2 = this.Job as IBackgroundCopyJob2;
            this.job3 = this.Job as IBackgroundCopyJob3;
            this.job4 = this.Job as IBackgroundCopyJob4;

            // store existing notification handler and route message to this as well otherwise it may break system
            // download jobs
            if (this.NotificationInterface != null)
            {
                this.NotificationTarget = this.NotificationInterface; // pointer to the existing one;
            }

            this.NotificationInterface = manager.NotificationHandler;

            // notification interface will be disabled when NotifyCmd is set
        }
Example #35
0
 protected virtual void Dispose(bool disposing)
 {
     if (!this.disposed)
     {
         if (disposing)
         {
             if (this.notificationTarget != null)
             {
                 this.NotificationInterface = this.notificationTarget;
             }
             if (this.files != null)
             {
                 this.files.Dispose();
             }
             this.job = null;
         }
     }
     disposed = true;
 }
Example #36
0
 public void JobModification(IBackgroundCopyJob pJob, uint dwReserved)
 {
     BitsJob job;
     if (null != this.onJobModified)
     {
         Guid guid;
         pJob.GetId(out guid);
         if (manager.Jobs.ContainsKey(guid))
         {
             job = manager.Jobs[guid];
         }
         else
         {
             // Update Joblist to check whether the job still exists. If not, just return
             manager.EnumJobs(manager.currentOwner);
             if (manager.Jobs.ContainsKey(guid))
             {
                 job = manager.Jobs[guid];
             }
             else
                 return;
         }
         this.onJobModified(this, new NotificationEventArgs(job));
         //forward event
         if (job.notificationTarget != null)
             job.notificationTarget.JobModification(pJob, dwReserved);
     }
 }
        /// <summary>
        /// Centralizes all chores related to stopping and cancelling a copy job, and getting back
        /// from BITS the errors incurred during the job.
        /// </summary>
        /// <param name="copyJob">reference to the copy job object (not job id)</param>
        /// <param name="errMessage">a cumulative error message passed by reference so
        /// that additions can be made</param>
        private void HandleDownloadErrorCancelJob( 
            IBackgroundCopyJob copyJob,
            ref string errMessage)
        {
            string					singleError = "";
            string					jobDesc = "";
            string					jobName = "";
            Guid					jobID = Guid.Empty;
            IBackgroundCopyError	copyError = null;

            try
            {
                //  check if job is null; don't try to clean up null references!
                if( null != copyJob )
                {
                    //  get information about this job for reporting the error
                    copyJob.GetDescription( out jobDesc );
                    copyJob.GetDisplayName( out jobName );
                    copyJob.GetId( out jobID );

                    //  find out what the error was
                    copyJob.GetError( out copyError );

                    // use the culture id specified in RESX to tell COM which culture to return err message in:
                    copyError.GetErrorDescription( (uint)CULTURE_ID_FOR_COM, out singleError );

                    //  add error to our "stack" of errors:
                    errMessage += singleError + Environment.NewLine;

                    //  notify BITS that we consider this job a loss, forget about it:
                    copyJob.Cancel();

                    //  remove job from collection
                    RemoveCopyJobEntry( jobID );

                    //  log error, but don't throw here; let dnldmgr take care of error
                    //  NOTE that errMessage is used cumulatively for full track of problem
                    errMessage = ApplicationUpdateManager.TraceWrite( "[BITSDownloader]", "RES_EXCEPTION_BITSBackgroundCopyError", jobID, jobName, jobDesc, errMessage );

                    ExceptionManager.Publish( new Exception( errMessage ) );
                }
            }
            finally
            {
                if( null != copyError )
                {
                    Marshal.ReleaseComObject( copyError );
                    copyError = null;
                }
            }
        }
Example #38
0
 protected virtual void Dispose(bool disposing)
 {
     if (!this.disposed)
     {
         if (disposing)
         {
             if (this.notificationTarget != null)
                 this.NotificationInterface = this.notificationTarget;
             if (this.files != null)
                 this.files.Dispose();
             this.job = null;
         }
     }
     disposed = true;
 }
Example #39
0
 internal ProxySettings(IBackgroundCopyJob job)
 {
     this.job = job;
     job.GetProxySettings(out proxyUsage, out proxyList, out proxyBypassList);
 }
        /// <summary>
        /// Internal copy-job factory method.  Used to coordinate all aspects of a job set-up, 
        /// which includes creating a copy manager, creating a job within it, setting download
        /// parameters, and adding the job to our tracking collection for cleanup later
        /// </summary>
        /// <param name="copyManager">null reference to copy manager</param>
        /// <param name="copyJob">null reference to copy job</param>
        /// <param name="jobID">null reference to job id guid</param>
        /// <param name="jobNameKey">the key used to look up the job name in the resource file</param>
        /// <param name="jobDescriptionKey">the key used to look up the job description in the resource file</param>
        private void CreateCopyJob( 
            out IBackgroundCopyManager copyManager,
            out IBackgroundCopyJob copyJob,
            ref Guid jobID,
            string jobNameKey,
            string jobDescriptionKey)
        {
            string jobName = Resource.ResourceManager[ jobNameKey ];
            string jobDesc = Resource.ResourceManager[ jobDescriptionKey ];

            //  wrap in try-finally so we can clean COM objects if unexpected error
            try
            {
                //  create the manager
                copyManager = (IBackgroundCopyManager) new BackgroundCopyManager();

                // create the job, set its description, use "out" semantics to get jobid and the actual job object
                copyManager.CreateJob(
                    jobName,
                    BG_JOB_TYPE.BG_JOB_TYPE_DOWNLOAD,
                    out jobID,
                    out copyJob );

                //  set useful description
                copyJob.SetDescription( jobDesc );

                //  ***
                //      SET UP BITS JOB SETTINGS--TIMEOUTS/RETRY ETC
                //      SEE THE FOLLOWING REFERENCES:
                //  **  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/ibackgroundcopyjob_setminimumretrydelay.asp?frame=true
                //  **  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/ibackgroundcopyjob_setnoprogresstimeout.asp?frame=true
                //  **  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/bg_job_priority.asp
                //  ***

                //  in constant set to 0; this makes BITS retry as soon as possible after an error
                copyJob.SetMinimumRetryDelay( (uint)BITS_SET_MINIMUM_RETRY_DELAY );
                //  in constant set to 5 seconds; BITS will set job to Error status if exceeded
                copyJob.SetNoProgressTimeout( (uint)BITS_SET_NO_PROGRESS_TIMEOUT );
                //  make this job the highest (but still background) priority--
                copyJob.SetPriority( BG_JOB_PRIORITY.BG_JOB_PRIORITY_HIGH );
                //  ***

                //  lock our internal collection of jobs, and add this job--we use this collection in Dispose()
                //  to tell BITS to Cancel() jobs--and remove them from the queue
                //  if we did not do this, BITS would continue for (by default) two weeks to download what we asked!
                lock( _jobs.SyncRoot )
                {
                    _jobs.Add( jobID, jobName );
                }
            }
            catch( Exception e )
            {
                //  bad to catch all exceptions, but OK because we adorn it with necessary additional info then pass it up as innerException
                string error = ApplicationUpdateManager.TraceWrite( e, "[BITSDownloader.CreateCopyJob]", "RES_EXCEPTION_BITSOtherError", jobID, jobName, jobDesc );
                //  publish
                Exception newE = new Exception( error, e );
                ExceptionManager.Publish( newE );
                //  rethrow;
                throw newE;
            }
        }