internal static unsafe Status Update(Entry newEntry, Entry_FC attributes)
 {
     byte[] buffer = new byte[EntryBuffer.MarshalSize];
     newEntry.Error = Status.Success;
     fixed (byte* numRef = buffer)
     {
         EntryBuffer* bufferPtr = (EntryBuffer*) numRef;
         bufferPtr[0] = newEntry.Info;
         bufferPtr->StructSize = EntryBuffer.MarshalSize;
         if ((attributes & Entry_FC.Headerinfo) == Entry_FC.None)
         {
             if (!UnsafeNclNativeMethods.UnsafeWinInetCache.SetUrlCacheEntryInfoW(newEntry.Key, numRef, attributes))
             {
                 newEntry.Error = (Status) Marshal.GetLastWin32Error();
             }
         }
         else
         {
             Entry entry = new Entry(newEntry.Key, newEntry.MaxBufferBytes);
             SafeUnlockUrlCacheEntryFile file = null;
             bool flag = false;
             try
             {
                 file = LookupFile(entry);
                 if (file == null)
                 {
                     newEntry.Error = entry.Error;
                     return newEntry.Error;
                 }
                 newEntry.Filename = entry.Filename;
                 newEntry.OriginalUrl = entry.OriginalUrl;
                 newEntry.FileExt = entry.FileExt;
                 attributes &= ~Entry_FC.Headerinfo;
                 if ((attributes & Entry_FC.Exptime) == Entry_FC.None)
                 {
                     newEntry.Info.ExpireTime = entry.Info.ExpireTime;
                 }
                 if ((attributes & Entry_FC.Modtime) == Entry_FC.None)
                 {
                     newEntry.Info.LastModifiedTime = entry.Info.LastModifiedTime;
                 }
                 if ((attributes & Entry_FC.Attribute) == Entry_FC.None)
                 {
                     newEntry.Info.EntryType = entry.Info.EntryType;
                     newEntry.Info.U.ExemptDelta = entry.Info.U.ExemptDelta;
                     if ((entry.Info.EntryType & EntryType.StickyEntry) == EntryType.StickyEntry)
                     {
                         attributes |= Entry_FC.ExemptDelta | Entry_FC.Attribute;
                     }
                 }
                 attributes &= ~(Entry_FC.Exptime | Entry_FC.Modtime);
                 flag = (entry.Info.EntryType & EntryType.Edited) != 0;
                 if (!flag)
                 {
                     entry.Info.EntryType |= EntryType.Edited;
                     if (Update(entry, Entry_FC.Attribute) != Status.Success)
                     {
                         newEntry.Error = entry.Error;
                         return newEntry.Error;
                     }
                 }
             }
             finally
             {
                 if (file != null)
                 {
                     file.Close();
                 }
             }
             Remove(entry);
             if (Commit(newEntry) != Status.Success)
             {
                 if (!flag)
                 {
                     entry.Info.EntryType &= ~EntryType.Edited;
                     Update(entry, Entry_FC.Attribute);
                 }
                 return newEntry.Error;
             }
             if (attributes != Entry_FC.None)
             {
                 Update(newEntry, attributes);
             }
         }
     }
     return newEntry.Error;
 }
        //
        // Updates a Cached Entry metadata according to attibutes flags.
        //
        internal static Status Update(Entry newEntry, Entry_FC attributes) {
            // Currently WinInet does not support headers update,
            // hence don't need space for them although we'll need recreate a cache entry
            // if headers update is requested

            byte[]  buffer = new byte[EntryBuffer.MarshalSize];
            newEntry.Error = Status.Success;
            unsafe {
                fixed (byte *bytePtr = buffer) {
                    EntryBuffer *ePtr = (EntryBuffer*) bytePtr;
                    *ePtr = newEntry.Info;
                    //set the version just in case
                    ePtr->StructSize =  EntryBuffer.MarshalSize;

                    if ((attributes & Entry_FC.Headerinfo) == 0) {
                        if (!UnsafeNclNativeMethods.UnsafeWinInetCache.SetUrlCacheEntryInfoW(newEntry.Key, bytePtr, attributes)) {
                            newEntry.Error = (Status)Marshal.GetLastWin32Error();
                        }
                    }
                    else {
                        // simulating headers update using Edited cache entry feature of WinInet
                        Entry oldEntry = new Entry(newEntry.Key, newEntry.MaxBufferBytes);

                        SafeUnlockUrlCacheEntryFile handle = null;
                        bool wasEdited = false;
                        try {
                            // lock the entry and get the filename out.
                            handle = LookupFile(oldEntry);
                            if (handle == null) {
                                //The same error would happen on update attributes, return it.
                                newEntry.Error = oldEntry.Error;
                                return newEntry.Error;
                            }

                            //Copy strings from old entry that are not present in the method parameters
                            newEntry.Filename       = oldEntry.Filename;
                            newEntry.OriginalUrl    = oldEntry.OriginalUrl;
                            newEntry.FileExt        = oldEntry.FileExt;

                            // We don't need to update this and some other attributes since will replace entire entry
                            attributes &= ~Entry_FC.Headerinfo;

                            //Copy attributes from an old entry that are not present in the method parameters
                            if ((attributes & Entry_FC.Exptime) == 0) {
                                newEntry.Info.ExpireTime = oldEntry.Info.ExpireTime;
                            }

                            if ((attributes & Entry_FC.Modtime) == 0) {
                                newEntry.Info.LastModifiedTime = oldEntry.Info.LastModifiedTime;
                            }

                            if ((attributes & Entry_FC.Attribute) == 0) {
                                newEntry.Info.EntryType = oldEntry.Info.EntryType;
                                newEntry.Info.U.ExemptDelta = oldEntry.Info.U.ExemptDelta;
                                if ((oldEntry.Info.EntryType & EntryType.StickyEntry) == EntryType.StickyEntry) {
                                    attributes |= (Entry_FC.Attribute | Entry_FC.ExemptDelta);
                                }
                            }

                            // Those attributes will be taken care of by Commit()
                            attributes &= ~(Entry_FC.Exptime|Entry_FC.Modtime);

                            wasEdited = (oldEntry.Info.EntryType & EntryType.Edited) != 0;

                            if (!wasEdited) {
                                // Prevent the file from being deleted on entry Remove (kinda hack)
                                oldEntry.Info.EntryType |= EntryType.Edited;
                                // Recursion!
                                if (Update(oldEntry, Entry_FC.Attribute) != Status.Success) {
                                    newEntry.Error = oldEntry.Error;
                                    return newEntry.Error;
                                }
                            }
                        }
                        finally {
                            if (handle != null) {
                                handle.Close();
                            }
                        }

                        // At this point we try to delete the exisintg item and create a new one with the same
                        // filename and the new headers.
                        //We wish to ignore any errors from Remove since are going to replace the entry.
                        Remove(oldEntry);
                        if (Commit(newEntry) != Status.Success) {
                            if (!wasEdited) {
                                //revert back the original entry type
                                oldEntry.Info.EntryType &= ~EntryType.Edited;
                                Update(oldEntry, Entry_FC.Attribute);
                                // Being already in error mode, cannot do much if Update fails.
                            }
                            return newEntry.Error;
                        }

                        // Now see what's left in attributes change request.
                        if (attributes != Entry_FC.None) {
                            Update(newEntry, attributes);
                        }
                        //At this point newEntry.Error should contain the resulting status
                        //and we replaced the entry in the cache with the same body
                        //but different headers. Some more attributes may have changed as well.
                    }
                }
            }

            return newEntry.Error;
        }
Esempio n. 3
0
        //
        // Updates a Cached Entry metadata according to attibutes flags.
        //
        internal static Status Update(Entry newEntry, Entry_FC attributes)
        {
            // Currently WinInet does not support headers update,
            // hence don't need space for them although we'll need recreate a cache entry
            // if headers update is requested

            byte[] buffer = new byte[EntryBuffer.MarshalSize];
            newEntry.Error = Status.Success;
            unsafe
            {
                fixed(byte *bytePtr = buffer)
                {
                    EntryBuffer *ePtr = (EntryBuffer *)bytePtr;

                    *ePtr = newEntry.Info;
                    //set the version just in case
                    ePtr->StructSize = EntryBuffer.MarshalSize;

                    if ((attributes & Entry_FC.Headerinfo) == 0)
                    {
                        if (!UnsafeNclNativeMethods.UnsafeWinInetCache.SetUrlCacheEntryInfoW(newEntry.Key, bytePtr, attributes))
                        {
                            newEntry.Error = (Status)Marshal.GetLastWin32Error();
                        }
                    }
                    else
                    {
                        // simulating headers update using Edited cache entry feature of WinInet
                        Entry oldEntry = new Entry(newEntry.Key, newEntry.MaxBufferBytes);

                        SafeUnlockUrlCacheEntryFile handle = null;
                        bool wasEdited = false;
                        try {
                            // lock the entry and get the filename out.
                            handle = LookupFile(oldEntry);
                            if (handle == null)
                            {
                                //The same error would happen on update attributes, return it.
                                newEntry.Error = oldEntry.Error;
                                return(newEntry.Error);
                            }

                            //Copy strings from old entry that are not present in the method parameters
                            newEntry.Filename    = oldEntry.Filename;
                            newEntry.OriginalUrl = oldEntry.OriginalUrl;
                            newEntry.FileExt     = oldEntry.FileExt;

                            // We don't need to update this and some other attributes since will replace entire entry
                            attributes &= ~Entry_FC.Headerinfo;

                            //Copy attributes from an old entry that are not present in the method parameters
                            if ((attributes & Entry_FC.Exptime) == 0)
                            {
                                newEntry.Info.ExpireTime = oldEntry.Info.ExpireTime;
                            }

                            if ((attributes & Entry_FC.Modtime) == 0)
                            {
                                newEntry.Info.LastModifiedTime = oldEntry.Info.LastModifiedTime;
                            }

                            if ((attributes & Entry_FC.Attribute) == 0)
                            {
                                newEntry.Info.EntryType     = oldEntry.Info.EntryType;
                                newEntry.Info.U.ExemptDelta = oldEntry.Info.U.ExemptDelta;
                                if ((oldEntry.Info.EntryType & EntryType.StickyEntry) == EntryType.StickyEntry)
                                {
                                    attributes |= (Entry_FC.Attribute | Entry_FC.ExemptDelta);
                                }
                            }

                            // Those attributes will be taken care of by Commit()
                            attributes &= ~(Entry_FC.Exptime | Entry_FC.Modtime);

                            wasEdited = (oldEntry.Info.EntryType & EntryType.Edited) != 0;

                            if (!wasEdited)
                            {
                                // Prevent the file from being deleted on entry Remove (kinda hack)
                                oldEntry.Info.EntryType |= EntryType.Edited;
                                // Recursion!
                                if (Update(oldEntry, Entry_FC.Attribute) != Status.Success)
                                {
                                    newEntry.Error = oldEntry.Error;
                                    return(newEntry.Error);
                                }
                            }
                        }
                        finally {
                            if (handle != null)
                            {
                                handle.Close();
                            }
                        }

                        // At this point we try to delete the exisintg item and create a new one with the same
                        // filename and the new headers.
                        //We wish to ignore any errors from Remove since are going to replace the entry.
                        Remove(oldEntry);
                        if (Commit(newEntry) != Status.Success)
                        {
                            if (!wasEdited)
                            {
                                //revert back the original entry type
                                oldEntry.Info.EntryType &= ~EntryType.Edited;
                                Update(oldEntry, Entry_FC.Attribute);
                                // Being already in error mode, cannot do much if Update fails.
                            }
                            return(newEntry.Error);
                        }

                        // Now see what's left in attributes change request.
                        if (attributes != Entry_FC.None)
                        {
                            Update(newEntry, attributes);
                        }
                        //At this point newEntry.Error should contain the resulting status
                        //and we replaced the entry in the cache with the same body
                        //but different headers. Some more attributes may have changed as well.
                    }
                }
            }

            return(newEntry.Error);
        }
        internal static unsafe Status Update(Entry newEntry, Entry_FC attributes)
        {
            byte[] buffer = new byte[EntryBuffer.MarshalSize];
            newEntry.Error = Status.Success;
            fixed(byte *numRef = buffer)
            {
                EntryBuffer *bufferPtr = (EntryBuffer *)numRef;

                bufferPtr[0]          = newEntry.Info;
                bufferPtr->StructSize = EntryBuffer.MarshalSize;
                if ((attributes & Entry_FC.Headerinfo) == Entry_FC.None)
                {
                    if (!UnsafeNclNativeMethods.UnsafeWinInetCache.SetUrlCacheEntryInfoW(newEntry.Key, numRef, attributes))
                    {
                        newEntry.Error = (Status)Marshal.GetLastWin32Error();
                    }
                }
                else
                {
                    Entry entry = new Entry(newEntry.Key, newEntry.MaxBufferBytes);
                    SafeUnlockUrlCacheEntryFile file = null;
                    bool flag = false;
                    try
                    {
                        file = LookupFile(entry);
                        if (file == null)
                        {
                            newEntry.Error = entry.Error;
                            return(newEntry.Error);
                        }
                        newEntry.Filename    = entry.Filename;
                        newEntry.OriginalUrl = entry.OriginalUrl;
                        newEntry.FileExt     = entry.FileExt;
                        attributes          &= ~Entry_FC.Headerinfo;
                        if ((attributes & Entry_FC.Exptime) == Entry_FC.None)
                        {
                            newEntry.Info.ExpireTime = entry.Info.ExpireTime;
                        }
                        if ((attributes & Entry_FC.Modtime) == Entry_FC.None)
                        {
                            newEntry.Info.LastModifiedTime = entry.Info.LastModifiedTime;
                        }
                        if ((attributes & Entry_FC.Attribute) == Entry_FC.None)
                        {
                            newEntry.Info.EntryType     = entry.Info.EntryType;
                            newEntry.Info.U.ExemptDelta = entry.Info.U.ExemptDelta;
                            if ((entry.Info.EntryType & EntryType.StickyEntry) == EntryType.StickyEntry)
                            {
                                attributes |= Entry_FC.ExemptDelta | Entry_FC.Attribute;
                            }
                        }
                        attributes &= ~(Entry_FC.Exptime | Entry_FC.Modtime);
                        flag        = (entry.Info.EntryType & EntryType.Edited) != 0;
                        if (!flag)
                        {
                            entry.Info.EntryType |= EntryType.Edited;
                            if (Update(entry, Entry_FC.Attribute) != Status.Success)
                            {
                                newEntry.Error = entry.Error;
                                return(newEntry.Error);
                            }
                        }
                    }
                    finally
                    {
                        if (file != null)
                        {
                            file.Close();
                        }
                    }
                    Remove(entry);
                    if (Commit(newEntry) != Status.Success)
                    {
                        if (!flag)
                        {
                            entry.Info.EntryType &= ~EntryType.Edited;
                            Update(entry, Entry_FC.Attribute);
                        }
                        return(newEntry.Error);
                    }
                    if (attributes != Entry_FC.None)
                    {
                        Update(newEntry, attributes);
                    }
                }
            }

            return(newEntry.Error);
        }