Example #1
0
        ///
        /// Thread Proc
        ///
        internal static void DownloadThreadProc()
        {
            Queue workQueue = _workQueue;

            for (;;)
            {
                _waitEvent.WaitOne();

                while (workQueue.Count != 0)
                {
                    QueueEntry entry = (QueueEntry)workQueue.Dequeue();

                    #pragma warning disable 6500

                    // Catch all exceptions and marshal them to the correct thread
                    try
                    {
                        entry.inputStream.BeginRead(
                            entry.readBuffer,
                            0,
                            READ_SIZE,
                            _readCallback,
                            entry
                            );
                    }
                    catch (Exception e)
                    {
                        MarshalException(entry, e);
                    }
                    finally
                    {
                        //
                        // This method never exits, and 'entry' is _not_ scoped
                        // to the while loop, so if we don't null entry out it will
                        // be rooted while _waitEvent.WaitOne() blocks.
                        //
                        entry = null;
                    }

                    #pragma warning restore 6500
                }
            }
        }
Example #2
0
        ///
        /// Begin a download
        ///
        internal static void BeginDownload(
            BitmapDecoder decoder,
            Uri uri,
            RequestCachePolicy uriCachePolicy,
            Stream stream
            )
        {
            lock (_syncLock)
            {
                if (!_thread.IsAlive)
                {
                    _thread.IsBackground = true;
                    _thread.Start();
                }
            }

            QueueEntry entry;

            // If there is already a download for this uri, just add the decoder to the list
            if (uri != null)
            {
                lock (_syncLock)
                {
                    if (_uriTable[uri] != null)
                    {
                        entry = (QueueEntry)_uriTable[uri];
                        entry.decoders.Add(new WeakReference(decoder));

                        return;
                    }
                }
            }

            entry          = new QueueEntry();
            entry.decoders = new List <WeakReference>();

            lock (_syncLock)
            {
                entry.decoders.Add(new WeakReference(decoder));
            }

            entry.inputUri    = uri;
            entry.inputStream = stream;

            string cacheFolder = MS.Win32.WinInet.InternetCacheFolder.LocalPath;
            bool   passed      = false;

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // BlessedAssert
            try
            {
                // Get the file path
                StringBuilder tmpFileName = new StringBuilder(NativeMethods.MAX_PATH);
                MS.Win32.UnsafeNativeMethods.GetTempFileName(cacheFolder, "WPF", 0, tmpFileName);

                try
                {
                    string         pathToUse  = tmpFileName.ToString();
                    SafeFileHandle fileHandle = MS.Win32.UnsafeNativeMethods.CreateFile(
                        pathToUse,
                        NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE, /* dwDesiredAccess */
                        0,                                                        /* dwShare */
                        null,                                                     /* lpSecurityAttributes */
                        NativeMethods.CREATE_ALWAYS,                              /* dwCreationDisposition */
                        NativeMethods.FILE_ATTRIBUTE_TEMPORARY |
                        NativeMethods.FILE_FLAG_DELETE_ON_CLOSE,                  /* dwFlagsAndAttributes */
                        IntPtr.Zero                                               /* hTemplateFile */
                        );

                    if (fileHandle.IsInvalid)
                    {
                        throw new Win32Exception();
                    }

                    entry.outputStream = new FileStream(fileHandle, FileAccess.ReadWrite);
                    entry.streamPath   = pathToUse;
                    passed             = true;
                }
                catch (Exception e)
                {
                    if (CriticalExceptions.IsCriticalException(e))
                    {
                        throw;
                    }
                }
            }
            finally
            {
                SecurityPermission.RevertAssert();
            }

            if (!passed)
            {
                throw new IOException(SR.Get(SRID.Image_CannotCreateTempFile));
            }

            entry.readBuffer    = new byte[READ_SIZE];
            entry.contentLength = -1;
            entry.contentType   = string.Empty;
            entry.lastPercent   = 0;

            // Add the entry to the table if we know the uri
            if (uri != null)
            {
                lock (_syncLock)
                {
                    _uriTable[uri] = entry;
                }
            }

            if (stream == null)
            {
                bool fElevate = false;
                if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
                {
                    SecurityHelper.BlockCrossDomainForHttpsApps(uri);

                    // In this case we first check to see if the consumer has media permissions for
                    // safe media (Site of Origin + Cross domain), if it
                    // does we assert and run the code that requires the assert
                    if (SecurityHelper.CallerHasMediaPermission(MediaPermissionAudio.NoAudio,
                                                                MediaPermissionVideo.NoVideo,
                                                                MediaPermissionImage.SafeImage))
                    {
                        fElevate = true;
                    }
                }

                // This is the case where we are accessing an http image from an http site and we have media permission
                if (fElevate)
                {
                    (new WebPermission(NetworkAccess.Connect, BindUriHelper.UriToString(uri))).Assert(); // BlessedAssert
                }
                try
                {
                    entry.webRequest = WpfWebRequestHelper.CreateRequest(uri);
                    if (uriCachePolicy != null)
                    {
                        entry.webRequest.CachePolicy = uriCachePolicy;
                    }
                }
                finally
                {
                    if (fElevate)
                    {
                        WebPermission.RevertAssert();
                    }
                }

                entry.webRequest.BeginGetResponse(_responseCallback, entry);
            }
            else
            {
                _workQueue.Enqueue(entry);
                // Signal
                _waitEvent.Set();
            }
        }
Example #3
0
        ///
        /// Read callback
        ///
        private static void ReadCallback(IAsyncResult result)
        {
            QueueEntry entry     = (QueueEntry)result.AsyncState;
            int        bytesRead = 0;

            #pragma warning disable 6500

            try
            {
                bytesRead = entry.inputStream.EndRead(result);
            }
            catch (Exception e)
            {
                MarshalException(entry, e);
            }

            #pragma warning restore 6500

            if (bytesRead == 0)
            {
                //
                // We're done reading from the input stream.
                //
                entry.inputStream.Close();
                entry.inputStream = null;

                //
                // We're done writing to the output stream. Make sure everything
                // is written to disk.
                //
                entry.outputStream.Flush();
                entry.outputStream.Seek(0, SeekOrigin.Begin);


                lock (_syncLock)
                {
                    // Fire download progress & completion event for each decoder
                    foreach (WeakReference decoderReference in entry.decoders)
                    {
                        LateBoundBitmapDecoder decoder = decoderReference.Target as LateBoundBitmapDecoder;
                        if (decoder != null)
                        {
                            //
                            // Marshal events to UI thread
                            //
                            MarshalEvents(
                                decoder,
                                new DispatcherOperationCallback(decoder.ProgressCallback),
                                100
                                );

                            MarshalEvents(
                                decoder,
                                new DispatcherOperationCallback(decoder.DownloadCallback),
                                entry.outputStream
                                );
                        }
                    }
                }

                // Delete entry from uri table
                if (entry.inputUri != null)
                {
                    lock (_syncLock)
                    {
                        _uriTable[entry.inputUri] = null;
                    }
                }
            }
            else
            {
                entry.outputStream.Write(entry.readBuffer, 0, bytesRead);

                if (entry.contentLength > 0)
                {
                    int percentComplete = (int)Math.Floor(100.0 * (double)entry.outputStream.Length / (double)entry.contentLength);

                    // Only raise if percentage went up by ~1% (ie value changed).
                    if (percentComplete != entry.lastPercent)
                    {
                        // Update last value
                        entry.lastPercent = percentComplete;

                        lock (_syncLock)
                        {
                            // Fire download progress event for each decoder
                            foreach (WeakReference decoderReference in entry.decoders)
                            {
                                LateBoundBitmapDecoder decoder = decoderReference.Target as LateBoundBitmapDecoder;
                                if (decoder != null)
                                {
                                    //
                                    // Marshal events to UI thread
                                    //
                                    MarshalEvents(
                                        decoder,
                                        new DispatcherOperationCallback(decoder.ProgressCallback),
                                        percentComplete
                                        );
                                }
                            }
                        }
                    }
                }

                _workQueue.Enqueue(entry);
                _waitEvent.Set();
            }
        }
Example #4
0
        /// 
        /// Marshal an exception to the Dispatcher thread
        /// 
        private static void MarshalException(
            QueueEntry entry,
            Exception e
            ) 
        {
            lock (_syncLock) 
            { 
                // Fire download completion event for each decoder
                foreach (LateBoundBitmapDecoder decoder in entry.decoders) 
                {
                    MarshalEvents(
                        decoder,
                        new DispatcherOperationCallback(decoder.ExceptionCallback), 
                        e
                        ); 
                } 

                if (entry.inputUri != null) 
                {
                    lock (_syncLock)
                    {
                        _uriTable[entry.inputUri] = null; 
                    }
                } 
            } 
        }
Example #5
0
        internal static void BeginDownload( 
            BitmapDecoder decoder,
            Uri uri, 
            RequestCachePolicy uriCachePolicy, 
            Stream stream
            ) 
        {
            lock (_syncLock)
            {
                if (!_thread.IsAlive) 
                {
                    _thread.IsBackground = true; 
                    _thread.Start(); 
                }
            } 

            QueueEntry entry;

            // If there is already a download for this uri, just add the decoder to the list 
            if (uri != null)
            { 
                lock (_syncLock) 
                {
                    if (_uriTable[uri] != null) 
                    {
                        entry = (QueueEntry)_uriTable[uri];
                        entry.decoders.Add(decoder);
 
                        return;
                    } 
                } 
            }
 
            entry = new QueueEntry();
            entry.decoders  = new List<BitmapDecoder>();

            lock (_syncLock) 
            {
                entry.decoders.Add(decoder); 
            } 

            entry.inputUri = uri; 
            entry.inputStream = stream;

            string cacheFolder = MS.Win32.WinInet.InternetCacheFolder.LocalPath;
            bool passed = false; 

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // BlessedAssert 
            try 
            {
                // Get the file path 
                StringBuilder tmpFileName = new StringBuilder(NativeMethods.MAX_PATH);
                MS.Win32.UnsafeNativeMethods.GetTempFileName(cacheFolder, "WPF", 0, tmpFileName);

                try 
                {
                    string pathToUse = tmpFileName.ToString(); 
                    SafeFileHandle fileHandle = MS.Win32.UnsafeNativeMethods.CreateFile( 
                        pathToUse,
                        NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE, /* dwDesiredAccess */ 
                        0,                                                        /* dwShare */
                        null,                                                     /* lpSecurityAttributes */
                        NativeMethods.CREATE_ALWAYS,                              /* dwCreationDisposition */
                        NativeMethods.FILE_ATTRIBUTE_TEMPORARY | 
                        NativeMethods.FILE_FLAG_DELETE_ON_CLOSE,                  /* dwFlagsAndAttributes */
                        IntPtr.Zero                                               /* hTemplateFile */ 
                        ); 

                    if (fileHandle.IsInvalid) 
                    {
                        throw new Win32Exception();
                    }
 
                    entry.outputStream = new FileStream(fileHandle, FileAccess.ReadWrite);
                    entry.streamPath = pathToUse; 
                    passed = true; 
                }
                catch(Exception e) 
                {
                    if (CriticalExceptions.IsCriticalException(e))
                    {
                        throw; 
                    }
                } 
            } 
            finally
            { 
                SecurityPermission.RevertAssert();
            }

            if (!passed) 
            {
                throw new IOException(SR.Get(SRID.Image_CannotCreateTempFile)); 
            } 

            entry.readBuffer  = new byte[READ_SIZE]; 
            entry.contentLength = -1;
            entry.contentType = string.Empty;
            entry.lastPercent = 0;
 
            // Add the entry to the table if we know the uri
            if (uri != null) 
            { 
                lock (_syncLock)
                { 
                    _uriTable[uri] = entry;
                }
            }
 
            if (stream == null)
            { 
                bool fElevate = false; 
                if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
                { 
                    SecurityHelper.BlockCrossDomainForHttpsApps(uri);

                    // In this case we first check to see if the consumer has media permissions for
                    // safe media (Site of Origin + Cross domain), if it 
                    // does we assert and run the code that requires the assert
                    if (SecurityHelper.CallerHasMediaPermission(MediaPermissionAudio.NoAudio, 
                                                                MediaPermissionVideo.NoVideo, 
                                                                MediaPermissionImage.SafeImage))
                    { 
                        fElevate = true;
                    }
                }
 
                // This is the case where we are accessing an http image from an http site and we have media permission
                if (fElevate) 
                { 
                    (new WebPermission(NetworkAccess.Connect, BindUriHelper.UriToString(uri))).Assert(); // BlessedAssert
                } 
                try
                {
                    entry.webRequest = WpfWebRequestHelper.CreateRequest(uri);
                    if (uriCachePolicy != null) 
                    {
                        entry.webRequest.CachePolicy = uriCachePolicy; 
                    } 
                }
                finally 
                {
                    if(fElevate)
                    {
                        WebPermission.RevertAssert(); 
                    }
                } 
 
                entry.webRequest.BeginGetResponse(_responseCallback, entry);
            } 
            else
            {
                _workQueue.Enqueue(entry);
                // Signal 
                _waitEvent.Set();
            } 
        } 
Example #6
0
        ///
        /// Begin a download
        ///
        internal static void BeginDownload(
            BitmapDecoder decoder,
            Uri uri,
            RequestCachePolicy uriCachePolicy,
            Stream stream
            )
        {
            lock (_syncLock)
            {
                if (!_thread.IsAlive)
                {
                    _thread.IsBackground = true;
                    _thread.Start();
                }
            }

            QueueEntry entry;

            // If there is already a download for this uri, just add the decoder to the list
            if (uri != null)
            {
                lock (_syncLock)
                {
                    if (_uriTable[uri] != null)
                    {
                        entry = (QueueEntry)_uriTable[uri];
                        entry.decoders.Add(new WeakReference(decoder));

                        return;
                    }
                }
            }

            entry          = new QueueEntry();
            entry.decoders = new List <WeakReference>();

            lock (_syncLock)
            {
                entry.decoders.Add(new WeakReference(decoder));
            }

            entry.inputUri    = uri;
            entry.inputStream = stream;

            string cacheFolder = MS.Win32.WinInet.InternetCacheFolder.LocalPath;
            bool   passed      = false;

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // BlessedAssert
            try
            {
                // Get the file path
                StringBuilder tmpFileName = new StringBuilder(NativeMethods.MAX_PATH);
                MS.Win32.UnsafeNativeMethods.GetTempFileName(cacheFolder, "WPF", 0, tmpFileName);

                try
                {
                    string         pathToUse  = tmpFileName.ToString();
                    SafeFileHandle fileHandle = MS.Win32.UnsafeNativeMethods.CreateFile(
                        pathToUse,
                        NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE, /* dwDesiredAccess */
                        0,                                                        /* dwShare */
                        null,                                                     /* lpSecurityAttributes */
                        NativeMethods.CREATE_ALWAYS,                              /* dwCreationDisposition */
                        NativeMethods.FILE_ATTRIBUTE_TEMPORARY |
                        NativeMethods.FILE_FLAG_DELETE_ON_CLOSE,                  /* dwFlagsAndAttributes */
                        IntPtr.Zero                                               /* hTemplateFile */
                        );

                    if (fileHandle.IsInvalid)
                    {
                        throw new Win32Exception();
                    }

                    entry.outputStream = new FileStream(fileHandle, FileAccess.ReadWrite);
                    entry.streamPath   = pathToUse;
                    passed             = true;
                }
                catch (Exception e)
                {
                    if (CriticalExceptions.IsCriticalException(e))
                    {
                        throw;
                    }
                }
            }
            finally
            {
                SecurityPermission.RevertAssert();
            }

            if (!passed)
            {
                throw new IOException(SR.Get(SRID.Image_CannotCreateTempFile));
            }

            entry.readBuffer    = new byte[READ_SIZE];
            entry.contentLength = -1;
            entry.contentType   = string.Empty;
            entry.lastPercent   = 0;

            // Add the entry to the table if we know the uri
            if (uri != null)
            {
                lock (_syncLock)
                {
                    _uriTable[uri] = entry;
                }
            }

            if (stream == null)
            {
                entry.webRequest = WpfWebRequestHelper.CreateRequest(uri);
                if (uriCachePolicy != null)
                {
                    entry.webRequest.CachePolicy = uriCachePolicy;
                }

                entry.webRequest.BeginGetResponse(_responseCallback, entry);
            }
            else
            {
                _workQueue.Enqueue(entry);
                // Signal
                _waitEvent.Set();
            }
        }