/// <summary>
        /// Checks that the resource is a <see cref="IDvResource"/> object.
        /// Calls base class and notifies owner of change.
        /// </summary>
        /// <param name="newResource"></param>
        /// <exception cref="InvalidCastException">
        /// Thrown if newResource is not a IDvResource.
        /// </exception>
        public override void AddResource(IMediaResource newResource)
        {
            IDvResource res = (IDvResource)newResource;

            base.AddResource(res);
            this.NotifyRootOfChange();
        }
        /// <summary>
        /// Checks that the resource is a <see cref="IDvResource"/> object.
        /// Calls base class and notifies owner of change.
        /// </summary>
        /// <param name="newResource"></param>
        /// <exception cref="InvalidCastException">
        /// Thrown if newResource is not a IDvResource.
        /// </exception>
        public override void AddResource(IMediaResource newResource)
        {
            // cast and throw exception if needed
            IDvResource res = (IDvResource)newResource;

            base.AddResource(res);
            this.NotifyRootOfChange();
        }
        /// <summary>
        /// Returns a <see cref="IDvResource"/> object assocated with the item.
        /// </summary>
        /// <param name="resourceID">the resource ID of the desired <see cref="IDvResource"/> object</param>
        /// <returns>The <see cref="IDvResource"/> instance, or null if it doesn't exist.</returns>
        protected internal IDvResource GetResource(string resourceID)
        {
            IDvResource retVal = null;

            this.m_LockResources.AcquireReaderLock(-1);

            if (this.m_Resources != null)
            {
                foreach (IDvResource res in this.m_Resources)
                {
                    if (res.ResourceID == resourceID)
                    {
                        retVal = res;
                        break;
                    }
                }
            }

            this.m_LockResources.ReleaseReaderLock();
            return(retVal);
        }
 private void Handle_OnRequestSaveBinary(MediaServerDevice sender, IDvResource res)
 {
     Exception error = null;
     this.m_LockRoot.WaitOne();
     try
     {// Throw exceptions if files are to not be deleted.
         //
         if (res.AllowImport == false)
         {
             throw new Error_AccessDenied("The resource cannot be overwritten or created.");
         }
     }
     catch (Exception e)
     {
         error = e;
     }
     this.m_LockRoot.ReleaseMutex();
     if (error != null)
     {
         throw new ApplicationException("Handle_OnRequestSaveBinary()", error);
     }
 }
        private void Handle_OnRequestDeleteBinary(MediaServerDevice sender, IDvResource res)
        {
            Exception error = null;
            this.m_LockRoot.WaitOne();
            try
            {

                // Throw exceptions if the file should not be deleted.
                //
                if (res.AllowImport == false)
                {
                    //throw new Error_AccessDenied("The resource cannot be deleted.");
                }

                /// The UPNP layer will not delete the actual file from the local file system.
                /// I should note that if multiple resources are bound to the same file, then
                /// the logic in this method prevents the file from being deleted.
                ///
                if (res.ContentUri.StartsWith(DvMediaResource.AUTOMAPFILE))
                {
                    string filename = res.ContentUri.Substring(DvMediaResource.AUTOMAPFILE.Length);
                    File.Delete(filename);
                }
            }
            catch (Exception e)
            {
                error = e;
            }
            this.m_LockRoot.ReleaseMutex();
            if (error != null)
            {
                throw new ApplicationException("Handle_OnRequestDeleteBinary()", error);
            }
        }
            /// <summary>
            /// Constructor - only created by <see cref="MediaServerDevice"/>
            /// when an HTTP-based file transfer occurs for either input or output from
            /// the server.
            /// </summary>
            /// <param name="incoming">required - indicates input or output direction</param>
            /// <param name="importExportTransfer">
            /// required - indicates if transfer was initiated from ImportResource or 
            /// ExportResource action request
            /// </param>
            /// <param name="session">
            /// required - the <see cref="HTTPSession"/> object that's
            /// carrying the stream.</param>
            /// <param name="res">
            /// required - the related <see cref="IDvResource"/> object
            /// that is related to the file transfer
            /// </param>
            /// <param name="stream">
            /// The stream object where the binary data is being stored or obtained from.
            /// </param>
            /// <param name="expectedLength">
            /// The length of the binary data, if known before hand.
            /// </param>
            internal HttpTransfer(bool incoming, bool importExportTransfer, HTTPSession session, IDvResource res, System.IO.Stream stream, long expectedLength)
            {
                this.Incoming = incoming;
                this.ImportExportTransfer = importExportTransfer;
                this.Session = session;

                // explicitly keep the source and remote
                // because if the session gets closed
                // they become null

                this.Source = session.Source;
                this.Destination = session.Remote;
                this.Resource = res;
                this.Stream = stream;
                this.m_TransferSize = expectedLength;
                this.ClosedOrDone = false;
                this.CriticalError = (session == null);
            }