internal RequestCacheEntry(_WinInetCache.Entry entry, bool isPrivateEntry)
 {
     this.m_IsPrivateEntry      = isPrivateEntry;
     this.m_StreamSize          = (entry.Info.SizeHigh << 0x20) | entry.Info.SizeLow;
     this.m_ExpiresUtc          = entry.Info.ExpireTime.IsNull ? DateTime.MinValue : DateTime.FromFileTimeUtc(entry.Info.ExpireTime.ToLong());
     this.m_HitCount            = entry.Info.HitRate;
     this.m_LastAccessedUtc     = entry.Info.LastAccessTime.IsNull ? DateTime.MinValue : DateTime.FromFileTimeUtc(entry.Info.LastAccessTime.ToLong());
     this.m_LastModifiedUtc     = entry.Info.LastModifiedTime.IsNull ? DateTime.MinValue : DateTime.FromFileTimeUtc(entry.Info.LastModifiedTime.ToLong());
     this.m_LastSynchronizedUtc = entry.Info.LastSyncTime.IsNull ? DateTime.MinValue : DateTime.FromFileTimeUtc(entry.Info.LastSyncTime.ToLong());
     this.m_MaxStale            = TimeSpan.FromSeconds((double)entry.Info.U.ExemptDelta);
     if (this.m_MaxStale == WinInetCache.s_MaxTimeSpanForInt32)
     {
         this.m_MaxStale = TimeSpan.MaxValue;
     }
     this.m_UsageCount     = entry.Info.UseCount;
     this.m_IsPartialEntry = (entry.Info.EntryType & _WinInetCache.EntryType.Sparse) != 0;
 }
Esempio n. 2
0
 // This ctor is for IERequestCache class only that relies on WinInet cache API.
 internal RequestCacheEntry(_WinInetCache.Entry entry, bool isPrivateEntry)
 {
     m_IsPrivateEntry      = isPrivateEntry;
     m_StreamSize          = ((long)entry.Info.SizeHigh << 32) | (long)((ulong)entry.Info.SizeLow);
     m_ExpiresUtc          = (entry.Info.ExpireTime.IsNull? DateTime.MinValue: DateTime.FromFileTimeUtc(entry.Info.ExpireTime.ToLong()));
     m_HitCount            = entry.Info.HitRate;
     m_LastAccessedUtc     = (entry.Info.LastAccessTime.IsNull? DateTime.MinValue: DateTime.FromFileTimeUtc(entry.Info.LastAccessTime.ToLong()));
     m_LastModifiedUtc     = (entry.Info.LastModifiedTime.IsNull? DateTime.MinValue: DateTime.FromFileTimeUtc(entry.Info.LastModifiedTime.ToLong()));
     m_LastSynchronizedUtc = (entry.Info.LastSyncTime.IsNull? DateTime.MinValue: DateTime.FromFileTimeUtc(entry.Info.LastSyncTime.ToLong()));
     m_MaxStale            = TimeSpan.FromSeconds(entry.Info.U.ExemptDelta);
     if (m_MaxStale == Microsoft.Win32.WinInetCache.s_MaxTimeSpanForInt32)
     {
         m_MaxStale = TimeSpan.MaxValue;
     }
     m_UsageCount     = entry.Info.UseCount;
     m_IsPartialEntry = (entry.Info.EntryType & _WinInetCache.EntryType.Sparse) != 0;
 }
 protected override void Dispose(bool disposing)
 {
     if ((Interlocked.Exchange(ref this.m_Disposed, 1) == 0) && (this.m_Entry != null))
     {
         System.Net.TriState unspecified;
         lock (this.m_Entry)
         {
             if (this.m_CallNesting == 0)
             {
                 base.Dispose(disposing);
             }
             else
             {
                 this.m_Event = new ManualResetEvent(false);
             }
         }
         if (disposing && (this.m_Event != null))
         {
             using (this.m_Event)
             {
                 this.m_Event.WaitOne();
                 lock (this.m_Entry)
                 {
                 }
             }
             base.Dispose(disposing);
         }
         if (this.m_StreamSize < 0L)
         {
             if (this.m_Aborted)
             {
                 if (this.m_OneWriteSucceeded)
                 {
                     unspecified = System.Net.TriState.Unspecified;
                 }
                 else
                 {
                     unspecified = System.Net.TriState.False;
                 }
             }
             else
             {
                 unspecified = System.Net.TriState.True;
             }
         }
         else if (!this.m_OneWriteSucceeded)
         {
             unspecified = System.Net.TriState.False;
         }
         else if (this.m_StreamSize > 0L)
         {
             unspecified = System.Net.TriState.Unspecified;
         }
         else
         {
             unspecified = System.Net.TriState.True;
         }
         if (unspecified == System.Net.TriState.False)
         {
             try
             {
                 if (Logging.On)
                 {
                     Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_no_commit", new object[] { "WinInetWriteStream.Close()" }));
                 }
                 System.IO.File.Delete(this.m_Entry.Filename);
             }
             catch (Exception exception)
             {
                 if (((exception is ThreadAbortException) || (exception is StackOverflowException)) || (exception is OutOfMemoryException))
                 {
                     throw;
                 }
                 if (Logging.On)
                 {
                     Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_error_deleting_filename", new object[] { "WinInetWriteStream.Close()", this.m_Entry.Filename }));
                 }
             }
             finally
             {
                 _WinInetCache.Status status = _WinInetCache.Remove(this.m_Entry);
                 if (((status != _WinInetCache.Status.Success) && (status != _WinInetCache.Status.FileNotFound)) && Logging.On)
                 {
                     Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_delete_failed", new object[] { "WinInetWriteStream.Close()", this.m_Entry.Key, new Win32Exception((int) this.m_Entry.Error).Message }));
                 }
                 this.m_Entry = null;
             }
         }
         else
         {
             this.m_Entry.OriginalUrl = null;
             if (unspecified == System.Net.TriState.Unspecified)
             {
                 if (((this.m_Entry.MetaInfo == null) || (this.m_Entry.MetaInfo.Length == 0)) || ((this.m_Entry.MetaInfo != "\r\n") && (this.m_Entry.MetaInfo.IndexOf("\r\n\r\n", StringComparison.Ordinal) == -1)))
                 {
                     this.m_Entry.MetaInfo = "\r\n~SPARSE_ENTRY:\r\n";
                 }
                 else
                 {
                     this.m_Entry.MetaInfo = this.m_Entry.MetaInfo + "~SPARSE_ENTRY:\r\n";
                 }
             }
             if (_WinInetCache.Commit(this.m_Entry) != _WinInetCache.Status.Success)
             {
                 if (Logging.On)
                 {
                     Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_commit_failed", new object[] { "WinInetWriteStream.Close()", this.m_Entry.Key, new Win32Exception((int) this.m_Entry.Error).Message }));
                 }
                 try
                 {
                     System.IO.File.Delete(this.m_Entry.Filename);
                 }
                 catch (Exception exception2)
                 {
                     if (((exception2 is ThreadAbortException) || (exception2 is StackOverflowException)) || (exception2 is OutOfMemoryException))
                     {
                         throw;
                     }
                     if (Logging.On)
                     {
                         Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_error_deleting_filename", new object[] { "WinInetWriteStream.Close()", this.m_Entry.Filename }));
                     }
                 }
                 if (this.m_IsThrow)
                 {
                     Win32Exception innerException = new Win32Exception((int) this.m_Entry.Error);
                     throw new IOException(SR.GetString("net_cache_retrieve_failure", new object[] { innerException.Message }), innerException);
                 }
             }
             else
             {
                 if (Logging.On)
                 {
                     if ((this.m_StreamSize > 0L) || ((this.m_StreamSize < 0L) && this.m_Aborted))
                     {
                         Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_committed_as_partial", new object[] { "WinInetWriteStream.Close()", this.m_Entry.Key, (this.m_StreamSize > 0L) ? this.m_StreamSize.ToString(CultureInfo.CurrentCulture) : SR.GetString("net_log_unknown") }));
                     }
                     Logging.PrintInfo(Logging.RequestCache, "WinInetWriteStream.Close(), Key = " + this.m_Entry.Key + ", Commit Status = " + this.m_Entry.Error.ToString());
                 }
                 if ((this.m_Entry.Info.EntryType & _WinInetCache.EntryType.StickyEntry) == _WinInetCache.EntryType.StickyEntry)
                 {
                     if (_WinInetCache.Update(this.m_Entry, _WinInetCache.Entry_FC.ExemptDelta) != _WinInetCache.Status.Success)
                     {
                         if (Logging.On)
                         {
                             Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_update_failed", new object[] { "WinInetWriteStream.Close(), Key = " + this.m_Entry.Key, new Win32Exception((int) this.m_Entry.Error).Message }));
                         }
                         if (this.m_IsThrow)
                         {
                             Win32Exception exception4 = new Win32Exception((int) this.m_Entry.Error);
                             throw new IOException(SR.GetString("net_cache_retrieve_failure", new object[] { exception4.Message }), exception4);
                         }
                         return;
                     }
                     if (Logging.On)
                     {
                         Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_max_stale_and_update_status", new object[] { "WinInetWriteFile.Close()", this.m_Entry.Info.U.ExemptDelta, this.m_Entry.Error.ToString() }));
                     }
                 }
                 base.Dispose(disposing);
             }
         }
     }
 }
 internal WriteStream(_WinInetCache.Entry entry, bool isThrow, long streamSize, bool async) : base(entry.Filename, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 0x1000, async)
 {
     this.m_Entry = entry;
     this.m_IsThrow = isThrow;
     this.m_StreamSize = streamSize;
     this.m_OneWriteSucceeded = streamSize == 0L;
     this.m_ReadTimeout = this.m_WriteTimeout = -1;
 }
 private Stream GetWriteStream(string key, long contentLength, DateTime expiresUtc, DateTime lastModifiedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata, bool isThrow)
 {
     if (Logging.On)
     {
         Logging.Enter(Logging.RequestCache, "WinInetCache.Store()", "Key = " + key);
     }
     if (key == null)
     {
         throw new ArgumentNullException("key");
     }
     if (!base.CanWrite)
     {
         if (Logging.On)
         {
             Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_operation_failed_with_error", new object[] { "WinInetCache.Store()", SR.GetString("net_cache_access_denied", new object[] { "Write" }) }));
         }
         if (Logging.On)
         {
             Logging.Exit(Logging.RequestCache, "WinInetCache.Store");
         }
         if (isThrow)
         {
             throw new InvalidOperationException(SR.GetString("net_cache_access_denied", new object[] { "Write" }));
         }
         return null;
     }
     _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength) {
         Key = key,
         OptionalLength = (contentLength < 0L) ? 0 : ((contentLength > 0x7fffffffL) ? 0x7fffffff : ((int) contentLength))
     };
     entry.Info.ExpireTime = _WinInetCache.FILETIME.Zero;
     if ((expiresUtc != DateTime.MinValue) && (expiresUtc > s_MinDateTimeUtcForFileTimeUtc))
     {
         entry.Info.ExpireTime = new _WinInetCache.FILETIME(expiresUtc.ToFileTimeUtc());
     }
     entry.Info.LastModifiedTime = _WinInetCache.FILETIME.Zero;
     if ((lastModifiedUtc != DateTime.MinValue) && (lastModifiedUtc > s_MinDateTimeUtcForFileTimeUtc))
     {
         entry.Info.LastModifiedTime = new _WinInetCache.FILETIME(lastModifiedUtc.ToFileTimeUtc());
     }
     entry.Info.EntryType = _WinInetCache.EntryType.NormalEntry;
     if (maxStale > TimeSpan.Zero)
     {
         if (maxStale >= s_MaxTimeSpanForInt32)
         {
             maxStale = s_MaxTimeSpanForInt32;
         }
         entry.Info.U.ExemptDelta = (int) maxStale.TotalSeconds;
         entry.Info.EntryType = _WinInetCache.EntryType.StickyEntry;
     }
     entry.MetaInfo = this.CombineMetaInfo(entryMetadata, systemMetadata);
     entry.FileExt = "cache";
     if (Logging.On)
     {
         Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_expected_length", new object[] { entry.OptionalLength }));
         Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_last_modified", new object[] { entry.Info.LastModifiedTime.IsNull ? "0" : DateTime.FromFileTimeUtc(entry.Info.LastModifiedTime.ToLong()).ToString("r") }));
         Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_expires", new object[] { entry.Info.ExpireTime.IsNull ? "0" : DateTime.FromFileTimeUtc(entry.Info.ExpireTime.ToLong()).ToString("r") }));
         Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_max_stale", new object[] { (maxStale > TimeSpan.Zero) ? ((int) maxStale.TotalSeconds).ToString() : "n/a" }));
         if (Logging.IsVerbose(Logging.RequestCache))
         {
             Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_dumping_metadata"));
             if (entry.MetaInfo.Length == 0)
             {
                 Logging.PrintInfo(Logging.RequestCache, "<null>");
             }
             else
             {
                 if (entryMetadata != null)
                 {
                     foreach (string str in entryMetadata)
                     {
                         Logging.PrintInfo(Logging.RequestCache, str.TrimEnd(RequestCache.LineSplits));
                     }
                 }
                 Logging.PrintInfo(Logging.RequestCache, "------");
                 if (systemMetadata != null)
                 {
                     foreach (string str2 in systemMetadata)
                     {
                         Logging.PrintInfo(Logging.RequestCache, str2.TrimEnd(RequestCache.LineSplits));
                     }
                 }
             }
         }
     }
     _WinInetCache.CreateFileName(entry);
     Stream @null = Stream.Null;
     if (entry.Error != _WinInetCache.Status.Success)
     {
         if (Logging.On)
         {
             Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_create_failed", new object[] { new Win32Exception((int) entry.Error).Message }));
             Logging.Exit(Logging.RequestCache, "WinInetCache.Store");
         }
         if (isThrow)
         {
             Win32Exception innerException = new Win32Exception((int) entry.Error);
             throw new IOException(SR.GetString("net_cache_retrieve_failure", new object[] { innerException.Message }), innerException);
         }
         return null;
     }
     try
     {
         @null = new WriteStream(entry, isThrow, contentLength, this.async);
     }
     catch (Exception exception2)
     {
         if (((exception2 is ThreadAbortException) || (exception2 is StackOverflowException)) || (exception2 is OutOfMemoryException))
         {
             throw;
         }
         if (Logging.On)
         {
             Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_exception", new object[] { "WinInetCache.Store()", exception2 }));
             Logging.Exit(Logging.RequestCache, "WinInetCache.Store");
         }
         if (isThrow)
         {
             throw;
         }
         return null;
     }
     if (Logging.On)
     {
         Logging.Exit(Logging.RequestCache, "WinInetCache.Store", "Filename = " + entry.Filename);
     }
     return @null;
 }
 private bool UpdateInfo(string key, DateTime expiresUtc, DateTime lastModifiedUtc, DateTime lastSynchronizedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata, bool isThrow)
 {
     if (key == null)
     {
         throw new ArgumentNullException("key");
     }
     if (Logging.On)
     {
         Logging.Enter(Logging.RequestCache, "WinInetCache.Update", "Key = " + key);
     }
     if (!base.CanWrite)
     {
         if (Logging.On)
         {
             Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_operation_failed_with_error", new object[] { "WinInetCache.Update()", SR.GetString("net_cache_access_denied", new object[] { "Write" }) }));
         }
         if (Logging.On)
         {
             Logging.Exit(Logging.RequestCache, "WinInetCache.Update()");
         }
         if (isThrow)
         {
             throw new InvalidOperationException(SR.GetString("net_cache_access_denied", new object[] { "Write" }));
         }
         return false;
     }
     _WinInetCache.Entry newEntry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength);
     _WinInetCache.Entry_FC none = _WinInetCache.Entry_FC.None;
     if ((expiresUtc != DateTime.MinValue) && (expiresUtc > s_MinDateTimeUtcForFileTimeUtc))
     {
         none |= _WinInetCache.Entry_FC.Exptime;
         newEntry.Info.ExpireTime = new _WinInetCache.FILETIME(expiresUtc.ToFileTimeUtc());
         if (Logging.On)
         {
             Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_set_expires", new object[] { expiresUtc.ToString("r") }));
         }
     }
     if ((lastModifiedUtc != DateTime.MinValue) && (lastModifiedUtc > s_MinDateTimeUtcForFileTimeUtc))
     {
         none |= _WinInetCache.Entry_FC.Modtime;
         newEntry.Info.LastModifiedTime = new _WinInetCache.FILETIME(lastModifiedUtc.ToFileTimeUtc());
         if (Logging.On)
         {
             Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_set_last_modified", new object[] { lastModifiedUtc.ToString("r") }));
         }
     }
     if ((lastSynchronizedUtc != DateTime.MinValue) && (lastSynchronizedUtc > s_MinDateTimeUtcForFileTimeUtc))
     {
         none |= _WinInetCache.Entry_FC.Synctime;
         newEntry.Info.LastSyncTime = new _WinInetCache.FILETIME(lastSynchronizedUtc.ToFileTimeUtc());
         if (Logging.On)
         {
             Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_set_last_synchronized", new object[] { lastSynchronizedUtc.ToString("r") }));
         }
     }
     if (maxStale != TimeSpan.MinValue)
     {
         none |= _WinInetCache.Entry_FC.ExemptDelta | _WinInetCache.Entry_FC.Attribute;
         newEntry.Info.EntryType = _WinInetCache.EntryType.NormalEntry;
         if (maxStale >= TimeSpan.Zero)
         {
             if (maxStale >= s_MaxTimeSpanForInt32)
             {
                 maxStale = s_MaxTimeSpanForInt32;
             }
             newEntry.Info.EntryType = _WinInetCache.EntryType.StickyEntry;
             newEntry.Info.U.ExemptDelta = (int) maxStale.TotalSeconds;
             if (Logging.On)
             {
                 object[] args = new object[] { ((int) maxStale.TotalSeconds).ToString() };
                 Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_enable_max_stale", args));
             }
         }
         else
         {
             newEntry.Info.U.ExemptDelta = 0;
             if (Logging.On)
             {
                 Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_disable_max_stale"));
             }
         }
     }
     newEntry.MetaInfo = this.CombineMetaInfo(entryMetadata, systemMetadata);
     if (newEntry.MetaInfo.Length != 0)
     {
         none |= _WinInetCache.Entry_FC.Headerinfo;
         if (Logging.On)
         {
             Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_dumping"));
             if (Logging.IsVerbose(Logging.RequestCache))
             {
                 Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_dumping"));
                 if (entryMetadata != null)
                 {
                     foreach (string str in entryMetadata)
                     {
                         Logging.PrintInfo(Logging.RequestCache, str.TrimEnd(RequestCache.LineSplits));
                     }
                 }
                 Logging.PrintInfo(Logging.RequestCache, "------");
                 if (systemMetadata != null)
                 {
                     foreach (string str2 in systemMetadata)
                     {
                         Logging.PrintInfo(Logging.RequestCache, str2.TrimEnd(RequestCache.LineSplits));
                     }
                 }
             }
         }
     }
     _WinInetCache.Update(newEntry, none);
     if (newEntry.Error != _WinInetCache.Status.Success)
     {
         if (Logging.On)
         {
             Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_update_failed", new object[] { "WinInetCache.Update()", newEntry.Key, new Win32Exception((int) newEntry.Error).Message }));
             Logging.Exit(Logging.RequestCache, "WinInetCache.Update()");
         }
         if (isThrow)
         {
             Win32Exception innerException = new Win32Exception((int) newEntry.Error);
             throw new IOException(SR.GetString("net_cache_retrieve_failure", new object[] { innerException.Message }), innerException);
         }
         return false;
     }
     if (Logging.On)
     {
         Logging.Exit(Logging.RequestCache, "WinInetCache.Update()", "Status = " + newEntry.Error.ToString());
     }
     return true;
 }
 internal bool TryRemove(string key, bool forceRemove)
 {
     if (key == null)
     {
         throw new ArgumentNullException("key");
     }
     if (!base.CanWrite)
     {
         if (Logging.On)
         {
             Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_operation_failed_with_error", new object[] { "WinInetCache.TryRemove()", SR.GetString("net_cache_access_denied", new object[] { "Write" }) }));
         }
         return false;
     }
     _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength);
     if ((_WinInetCache.Remove(entry) == _WinInetCache.Status.Success) || (entry.Error == _WinInetCache.Status.FileNotFound))
     {
         if (Logging.On)
         {
             Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_key_status", new object[] { "WinInetCache.TryRemove()", key, entry.Error.ToString() }));
         }
         return true;
     }
     if (!forceRemove)
     {
         if (Logging.On)
         {
             Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_key_remove_failed_status", new object[] { "WinInetCache.TryRemove()", key, entry.Error.ToString() }));
         }
         return false;
     }
     if (_WinInetCache.LookupInfo(entry) == _WinInetCache.Status.Success)
     {
         while (entry.Info.UseCount != 0)
         {
             if (Logging.On)
             {
                 Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_key_status", new object[] { "WinInetCache.TryRemove()", key, entry.Error.ToString() }));
             }
             if (Logging.On)
             {
                 Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_usecount_file", new object[] { "WinInetCache.TryRemove()", entry.Info.UseCount, entry.Filename }));
             }
             if (!UnsafeNclNativeMethods.UnsafeWinInetCache.UnlockUrlCacheEntryFileW(key, 0))
             {
                 break;
             }
             _WinInetCache.Status info = _WinInetCache.LookupInfo(entry);
         }
     }
     _WinInetCache.Remove(entry);
     if ((entry.Error != _WinInetCache.Status.Success) && (_WinInetCache.LookupInfo(entry) == _WinInetCache.Status.FileNotFound))
     {
         entry.Error = _WinInetCache.Status.Success;
     }
     if (Logging.On)
     {
         Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_key_status", new object[] { "WinInetCache.TryRemove()", key, entry.Error.ToString() }));
     }
     return (entry.Error == _WinInetCache.Status.Success);
 }
 internal override void Remove(string key)
 {
     if (key == null)
     {
         throw new ArgumentNullException("key");
     }
     if (!base.CanWrite)
     {
         if (Logging.On)
         {
             Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_operation_failed_with_error", new object[] { "WinInetCache.Remove()", SR.GetString("net_cache_access_denied", new object[] { "Write" }) }));
         }
     }
     else
     {
         _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength);
         if ((_WinInetCache.Remove(entry) != _WinInetCache.Status.Success) && (entry.Error != _WinInetCache.Status.FileNotFound))
         {
             Win32Exception innerException = new Win32Exception((int) entry.Error);
             if (Logging.On)
             {
                 Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_cannot_remove", new object[] { "WinInetCache.Remove()", key, innerException.Message }));
             }
             throw new IOException(SR.GetString("net_cache_retrieve_failure", new object[] { innerException.Message }), innerException);
         }
         if (Logging.On)
         {
             Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_key_status", new object[] { "WinInetCache.Remove(), ", key, entry.Error.ToString() }));
         }
     }
 }
 private unsafe Stream Lookup(string key, out RequestCacheEntry cacheEntry, bool isThrow)
 {
     if (Logging.On)
     {
         Logging.Enter(Logging.RequestCache, "WinInetCache.Retrieve", "key = " + key);
     }
     if (key == null)
     {
         throw new ArgumentNullException("key");
     }
     Stream @null = Stream.Null;
     SafeUnlockUrlCacheEntryFile handle = null;
     _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength);
     try
     {
         handle = _WinInetCache.LookupFile(entry);
         if (entry.Error == _WinInetCache.Status.Success)
         {
             if (Logging.On)
             {
                 Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_filename", new object[] { "WinInetCache.Retrieve()", entry.Filename, entry.Error }));
             }
             cacheEntry = new RequestCacheEntry(entry, base.IsPrivateCache);
             if ((entry.MetaInfo != null) && (entry.MetaInfo.Length != 0))
             {
                 int startIndex = 0;
                 int length = entry.MetaInfo.Length;
                 StringCollection strings = new StringCollection();
                 fixed (char* str2 = ((char*) entry.MetaInfo))
                 {
                     char* chPtr = str2;
                     for (int i = 0; i < length; i++)
                     {
                         if ((((i == startIndex) && ((i + 2) < length)) && (chPtr[i] == '~')) && (((chPtr[i + 1] == 'U') || (chPtr[i + 1] == 'u')) && (chPtr[i + 2] == ':')))
                         {
                             while ((i < length) && (chPtr[++i] != '\n'))
                             {
                             }
                             startIndex = i + 1;
                         }
                         else if (((i + 1) == length) || (chPtr[i] == '\n'))
                         {
                             string str = entry.MetaInfo.Substring(startIndex, ((chPtr[i - 1] == '\r') ? (i - 1) : (i + 1)) - startIndex);
                             if ((str.Length == 0) && (cacheEntry.EntryMetadata == null))
                             {
                                 cacheEntry.EntryMetadata = strings;
                                 strings = new StringCollection();
                             }
                             else if ((cacheEntry.EntryMetadata != null) && str.StartsWith("~SPARSE_ENTRY:", StringComparison.Ordinal))
                             {
                                 cacheEntry.IsPartialEntry = true;
                             }
                             else
                             {
                                 strings.Add(str);
                             }
                             startIndex = i + 1;
                         }
                     }
                 }
                 if (cacheEntry.EntryMetadata == null)
                 {
                     cacheEntry.EntryMetadata = strings;
                 }
                 else
                 {
                     cacheEntry.SystemMetadata = strings;
                 }
             }
             @null = new ReadStream(entry, handle, this.async);
         }
         else
         {
             if (handle != null)
             {
                 handle.Close();
             }
             cacheEntry = new RequestCacheEntry();
             cacheEntry.IsPrivateEntry = base.IsPrivateCache;
             if (entry.Error != _WinInetCache.Status.FileNotFound)
             {
                 if (Logging.On)
                 {
                     Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_lookup_failed", new object[] { "WinInetCache.Retrieve()", new Win32Exception((int) entry.Error).Message }));
                 }
                 if (Logging.On)
                 {
                     Logging.Exit(Logging.RequestCache, "WinInetCache.Retrieve()");
                 }
                 if (isThrow)
                 {
                     Win32Exception innerException = new Win32Exception((int) entry.Error);
                     throw new IOException(SR.GetString("net_cache_retrieve_failure", new object[] { innerException.Message }), innerException);
                 }
                 return null;
             }
         }
     }
     catch (Exception exception2)
     {
         if (((exception2 is ThreadAbortException) || (exception2 is StackOverflowException)) || (exception2 is OutOfMemoryException))
         {
             throw;
         }
         if (Logging.On)
         {
             Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_exception", new object[] { "WinInetCache.Retrieve()", exception2.ToString() }));
         }
         if (Logging.On)
         {
             Logging.Exit(Logging.RequestCache, "WinInetCache.Retrieve()");
         }
         if (handle != null)
         {
             handle.Close();
         }
         @null.Close();
         @null = Stream.Null;
         cacheEntry = new RequestCacheEntry();
         cacheEntry.IsPrivateEntry = base.IsPrivateCache;
         if (isThrow)
         {
             throw;
         }
         return null;
     }
     if (Logging.On)
     {
         Logging.Exit(Logging.RequestCache, "WinInetCache.Retrieve()", "Status = " + entry.Error.ToString());
     }
     return @null;
 }
            protected override void Dispose(bool disposing)
            {
                //if m_Entry is null, it means that the base constructor failed
                if (Interlocked.Exchange(ref m_Disposed, 1) == 0 && m_Entry != null) {

                    lock (m_Entry)
                    {
                        if (m_CallNesting == 0)
                            base.Dispose(disposing);
                        else
                            m_Event = new ManualResetEvent(false);
                    }

                    //
                    // This assumes the FileStream will never hang on write
                    //
                    if (disposing && m_Event != null)
                    {
                        using (m_Event)
                        {
                            m_Event.WaitOne();
                            lock (m_Entry) 
                            {
                                Debug.Assert(m_CallNesting == 0);
                            }
                        }
                        base.Dispose(disposing);
                    }

                    // We use TriState to indicate:
                    //     False:   Delete
                    //     Unknown: Partial
                    //     True:    Full
                    TriState cacheCommitAction;
                    if (m_StreamSize < 0)
                    {
                        if (m_Aborted)
                        {
                            if (m_OneWriteSucceeded)
                                cacheCommitAction = TriState.Unspecified; // Partial
                            else
                                cacheCommitAction = TriState.False; // Delete
                        }
                        else
                        {
                            cacheCommitAction = TriState.True; // Full
                        }
                    }
                    else
                    {
                        if (!m_OneWriteSucceeded)
                        {
                            cacheCommitAction = TriState.False; // Delete
                        }
                        else
                        {
                            if (m_StreamSize > 0)
                                cacheCommitAction = TriState.Unspecified; // Partial
                            else
                                cacheCommitAction = TriState.True; // Full
                        }
                    }

                    if (cacheCommitAction == TriState.False)
                    {
                        try
                        {
                            if(Logging.On)Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_no_commit, "WinInetWriteStream.Close()"));
                            // Delete temp cache file
                            File.Delete(m_Entry.Filename);
                        }
                        catch (Exception exception)
                        {
                            if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
                                throw;
                            }
                            if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_error_deleting_filename, "WinInetWriteStream.Close()", m_Entry.Filename));
                        }
                        finally {
                            //Delete an old entry if there was one
                            _WinInetCache.Status errorStatus = _WinInetCache.Remove(m_Entry);
                            if (errorStatus != _WinInetCache.Status.Success && errorStatus != _WinInetCache.Status.FileNotFound)
                            {
                                if(Logging.On)Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_delete_failed, "WinInetWriteStream.Close()", m_Entry.Key, new Win32Exception((int)m_Entry.Error).Message));
                            }

                            m_Entry = null;
                        }
                        return;
                    }

                    m_Entry.OriginalUrl = null;

                    //
                    // ATTN: WinIent currently does NOT support _WinInetCache.EntryType.Sparse
                    // USING a workaround
                    //
                    if (cacheCommitAction == TriState.Unspecified)
                    {
    // WinInet will not report this entry back we set this flag
    //                    m_Entry.Info.EntryType |= _WinInetCache.EntryType.Sparse;  // does not work for now

                        // HACK: WinInet does not support SPARSE_ENTRY bit
                        // We want to add c_SPARSE_ENTRY_HACK into the systemmetadata i.e. to the second block of strings separated by an empty line (\r\n).
                        if (m_Entry.MetaInfo == null || m_Entry.MetaInfo.Length == 0 ||
                            (m_Entry.MetaInfo != "\r\n" && m_Entry.MetaInfo.IndexOf("\r\n\r\n", StringComparison.Ordinal) == -1))
                        {
                            m_Entry.MetaInfo = "\r\n"+ WinInetCache.c_SPARSE_ENTRY_HACK+"\r\n";
                        }
                        else
                        {
                            m_Entry.MetaInfo += WinInetCache.c_SPARSE_ENTRY_HACK+"\r\n";
                        }
                    }

                    if (_WinInetCache.Commit(m_Entry) != _WinInetCache.Status.Success)
                    {
                        if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_commit_failed, "WinInetWriteStream.Close()", m_Entry.Key, new Win32Exception((int)m_Entry.Error).Message));
                        try
                        {
                            // Delete temp cache file
                            File.Delete(m_Entry.Filename);
                        }
                        catch (Exception exception)
                        {
                            if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
                                throw;
                            }
                            if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_error_deleting_filename, "WinInetWriteStream.Close()", m_Entry.Filename));
                        }

                        if (m_IsThrow)
                        {
                            Win32Exception win32Exception = new Win32Exception((int)m_Entry.Error);
                            throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, win32Exception.Message), win32Exception);
                        }
                        return;
                    }

                    if(Logging.On)
                    {
                        if (m_StreamSize > 0 || (m_StreamSize < 0 && m_Aborted))
                            Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_committed_as_partial, "WinInetWriteStream.Close()", m_Entry.Key, (m_StreamSize > 0 ? m_StreamSize.ToString(CultureInfo.CurrentCulture) : SR.GetString(SR.net_log_unknown))));
                        Logging.PrintInfo(Logging.RequestCache, "WinInetWriteStream.Close(), Key = " + m_Entry.Key + ", Commit Status = " + m_Entry.Error.ToString());
                    }


                    if ((m_Entry.Info.EntryType & _WinInetCache.EntryType.StickyEntry) == _WinInetCache.EntryType.StickyEntry)
                    {
                        if (_WinInetCache.Update(m_Entry, _WinInetCache.Entry_FC.ExemptDelta) != _WinInetCache.Status.Success)
                        {
                            if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_update_failed, "WinInetWriteStream.Close(), Key = " + m_Entry.Key, new Win32Exception((int)m_Entry.Error).Message));
                            if (m_IsThrow)
                            {
                                Win32Exception win32Exception = new Win32Exception((int)m_Entry.Error);
                                throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, win32Exception.Message), win32Exception);
                            }
                            return;
                        }
                        if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_max_stale_and_update_status, "WinInetWriteFile.Close()", m_Entry.Info.U.ExemptDelta, m_Entry.Error.ToString()));
                    }

                    base.Dispose(disposing);
                }
            }
            internal WriteStream(_WinInetCache.Entry entry, bool isThrow, long streamSize, bool async):
                    base(entry.Filename, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, async) {

                m_Entry = entry;
                m_IsThrow = isThrow;
                m_StreamSize = streamSize;
                m_OneWriteSucceeded = streamSize == 0; //if 0 is expected or the lenght is unknonw we will commit even an emtpy stream.
                m_ReadTimeout = m_WriteTimeout = System.Threading.Timeout.Infinite;
            }
        //
        //
        private bool UpdateInfo(string key, DateTime expiresUtc, DateTime lastModifiedUtc, DateTime lastSynchronizedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata, bool isThrow)
        {
            if (key == null) {
                throw new ArgumentNullException("key");
            }

            if(Logging.On) Logging.Enter(Logging.RequestCache, "WinInetCache.Update", "Key = "+ key);

            if (!CanWrite)
            {
                if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_operation_failed_with_error, "WinInetCache.Update()", SR.GetString(SR.net_cache_access_denied, "Write")));
                if(Logging.On) Logging.Exit(Logging.RequestCache, "WinInetCache.Update()");
                if(isThrow)
                {
                    throw new InvalidOperationException(SR.GetString(SR.net_cache_access_denied, "Write"));
                }
                return false;
            }

            _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength);
            _WinInetCache.Entry_FC attributes =  _WinInetCache.Entry_FC.None;

            if (expiresUtc != DateTime.MinValue && expiresUtc > s_MinDateTimeUtcForFileTimeUtc) {
                attributes |= _WinInetCache.Entry_FC.Exptime;
                entry.Info.ExpireTime = new _WinInetCache.FILETIME(expiresUtc.ToFileTimeUtc());
                if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_set_expires, expiresUtc.ToString("r")));
            }

            if (lastModifiedUtc != DateTime.MinValue && lastModifiedUtc > s_MinDateTimeUtcForFileTimeUtc) {
                attributes |= _WinInetCache.Entry_FC.Modtime;
                entry.Info.LastModifiedTime = new _WinInetCache.FILETIME(lastModifiedUtc.ToFileTimeUtc());
                if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_set_last_modified, lastModifiedUtc.ToString("r")));
            }

            if (lastSynchronizedUtc != DateTime.MinValue && lastSynchronizedUtc > s_MinDateTimeUtcForFileTimeUtc) {
                attributes |= _WinInetCache.Entry_FC.Synctime;
                entry.Info.LastSyncTime = new _WinInetCache.FILETIME(lastSynchronizedUtc.ToFileTimeUtc());
                if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_set_last_synchronized, lastSynchronizedUtc.ToString("r")));
            }

            if (maxStale != TimeSpan.MinValue) {
                attributes |= _WinInetCache.Entry_FC.ExemptDelta|_WinInetCache.Entry_FC.Attribute;
                entry.Info.EntryType = _WinInetCache.EntryType.NormalEntry;
                if (maxStale >= TimeSpan.Zero) {
                    if (maxStale >= s_MaxTimeSpanForInt32) {
                        maxStale = s_MaxTimeSpanForInt32;
                    }
                    entry.Info.EntryType = _WinInetCache.EntryType.StickyEntry;
                    entry.Info.U.ExemptDelta = (int)maxStale.TotalSeconds;
                    if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_enable_max_stale, ((int)maxStale.TotalSeconds).ToString()));
                }
                else {
                    entry.Info.U.ExemptDelta = 0;
                    if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_disable_max_stale));
                }
            }

            entry.MetaInfo = CombineMetaInfo(entryMetadata, systemMetadata);
            if (entry.MetaInfo.Length != 0) {
                attributes |= _WinInetCache.Entry_FC.Headerinfo;

                if(Logging.On) {
                    Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_dumping));
                    if (Logging.IsVerbose(Logging.RequestCache)) {
                        Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_dumping));
                        if (entryMetadata != null) {
                            foreach (string s in entryMetadata)
                            {
                                Logging.PrintInfo(Logging.RequestCache, s.TrimEnd(LineSplits));
                            }
                        }
                        Logging.PrintInfo(Logging.RequestCache, "------");
                        if (systemMetadata != null) {
                            foreach (string s in systemMetadata)
                            {
                                Logging.PrintInfo(Logging.RequestCache, s.TrimEnd(LineSplits));
                            }
                        }
                    }
                }
            }

            _WinInetCache.Update(entry, attributes) ;

            if (entry.Error != _WinInetCache.Status.Success) {
                if(Logging.On)
                {
                    Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_update_failed, "WinInetCache.Update()", entry.Key, new Win32Exception((int)entry.Error).Message));
                    Logging.Exit(Logging.RequestCache, "WinInetCache.Update()");
                }
                if (isThrow)
                {
                    Win32Exception win32Exception = new Win32Exception((int)entry.Error);
                    throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, win32Exception.Message), win32Exception);
                }
                return false;
            }

            if(Logging.On) Logging.Exit(Logging.RequestCache, "WinInetCache.Update()", "Status = " + entry.Error.ToString());
            return true;
        }
        //
        //
        private Stream GetWriteStream(string key, long contentLength, DateTime expiresUtc, DateTime lastModifiedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata, bool isThrow)
        {
            if(Logging.On) Logging.Enter(Logging.RequestCache, "WinInetCache.Store()", "Key = " + key);

            if (key == null) {
                throw new ArgumentNullException("key");
            }

            if (!CanWrite)
            {
                if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_operation_failed_with_error, "WinInetCache.Store()", SR.GetString(SR.net_cache_access_denied, "Write")));
                if(Logging.On) Logging.Exit(Logging.RequestCache, "WinInetCache.Store");
                if(isThrow)
                {
                    throw new InvalidOperationException(SR.GetString(SR.net_cache_access_denied, "Write"));
                }
                return null;
            }


            _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength);

            entry.Key = key;
            entry.OptionalLength = (contentLength < 0L)? 0: contentLength > Int32.MaxValue? Int32.MaxValue: (int)(contentLength);

            entry.Info.ExpireTime = _WinInetCache.FILETIME.Zero;
            if (expiresUtc != DateTime.MinValue && expiresUtc > s_MinDateTimeUtcForFileTimeUtc) {
                entry.Info.ExpireTime  = new _WinInetCache.FILETIME(expiresUtc.ToFileTimeUtc());
            }

            entry.Info.LastModifiedTime = _WinInetCache.FILETIME.Zero;
            if (lastModifiedUtc != DateTime.MinValue && lastModifiedUtc > s_MinDateTimeUtcForFileTimeUtc) {
                entry.Info.LastModifiedTime = new _WinInetCache.FILETIME(lastModifiedUtc.ToFileTimeUtc());
            }

            entry.Info.EntryType = _WinInetCache.EntryType.NormalEntry;
            if (maxStale > TimeSpan.Zero) {
                if (maxStale >= s_MaxTimeSpanForInt32) {
                    maxStale = s_MaxTimeSpanForInt32;
                }
                entry.Info.U.ExemptDelta = (int)maxStale.TotalSeconds;
                entry.Info.EntryType = _WinInetCache.EntryType.StickyEntry;
            }


            entry.MetaInfo = CombineMetaInfo(entryMetadata, systemMetadata);

            entry.FileExt = "cache";
            if(Logging.On) {
                Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_expected_length, entry.OptionalLength));
                Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_last_modified, (entry.Info.LastModifiedTime.IsNull? "0": DateTime.FromFileTimeUtc(entry.Info.LastModifiedTime.ToLong()).ToString("r"))));
                Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_expires, (entry.Info.ExpireTime.IsNull? "0": DateTime.FromFileTimeUtc(entry.Info.ExpireTime.ToLong()).ToString("r"))));
                Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_max_stale, (maxStale > TimeSpan.Zero? ((int)maxStale.TotalSeconds).ToString():"n/a")));
                if (Logging.IsVerbose(Logging.RequestCache)) {
                    Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_dumping_metadata));
                    if (entry.MetaInfo.Length == 0) {
                        Logging.PrintInfo(Logging.RequestCache, "<null>");
                    }
                    else {
                        if (entryMetadata != null) {
                            foreach (string s in entryMetadata)
                            {
                                Logging.PrintInfo(Logging.RequestCache, s.TrimEnd(LineSplits));
                            }
                        }
                        Logging.PrintInfo(Logging.RequestCache, "------");
                        if (systemMetadata != null) {
                            foreach (string s in systemMetadata)
                            {
                                Logging.PrintInfo(Logging.RequestCache, s.TrimEnd(LineSplits));
                            }
                        }
                    }
                }
            }

            _WinInetCache.CreateFileName(entry);

            Stream result = Stream.Null;
            if (entry.Error != _WinInetCache.Status.Success) {
                if(Logging.On)
                {
                    Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_create_failed, new Win32Exception((int)entry.Error).Message));
                    Logging.Exit(Logging.RequestCache, "WinInetCache.Store");
                }
                if (isThrow)
                {
                    Win32Exception win32Exception = new Win32Exception((int)entry.Error);
                    throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, win32Exception.Message), win32Exception);
                }
                return null;
            }


            try {
                result = new WriteStream(entry, isThrow, contentLength, async);
            }
            catch (Exception exception) {
                if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
                    throw;
                }

                if(Logging.On)
                {
                    Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_exception, "WinInetCache.Store()", exception));
                    Logging.Exit(Logging.RequestCache, "WinInetCache.Store");
                }
                if (isThrow)
                {
                    throw;
                }
                return null;
            }

            if(Logging.On) Logging.Exit(Logging.RequestCache, "WinInetCache.Store", "Filename = " + entry.Filename);
            return result;
        }
        //
        //
        //
        private Stream Lookup(string key, out RequestCacheEntry cacheEntry, bool isThrow)
        {
            if(Logging.On) Logging.Enter(Logging.RequestCache, "WinInetCache.Retrieve", "key = " + key);

            if (key == null) {
                throw new ArgumentNullException("key");
            }

            Stream result = Stream.Null;
            SafeUnlockUrlCacheEntryFile handle = null;
            _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength);
            try {
                handle = _WinInetCache.LookupFile(entry);

                if (entry.Error == _WinInetCache.Status.Success) {
                    if(Logging.On) Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_filename, "WinInetCache.Retrieve()", entry.Filename, entry.Error));

                    cacheEntry = new RequestCacheEntry(entry, IsPrivateCache);

                    if (entry.MetaInfo != null && entry.MetaInfo.Length != 0)
                    {
                        // convert metadata to upto two string collections
                        unsafe
                        {
                            int start = 0;
                            int length = entry.MetaInfo.Length;
                            StringCollection sc = new StringCollection();
                            fixed (char * ch = entry.MetaInfo)
                            {
                                int i;
                                for (i = 0; i < length; ++i)
                                {
                                    // WinInet specific block!!
                                    // The point here is that wininet scans for ~U: throughly with no regard to \r\n so we mimic the same behavior
                                    if (i == start && i+2 < length)
                                    {
                                        if (ch[i] == '~' && (ch[i+1] == 'U' || ch[i+1] == 'u') && ch[i+2] == ':')
                                        {
                                            //Security: don't report what the username is
                                            while(i < length && ch[++i] != '\n') {;}
                                            start = i+1;
                                            continue;
                                        }

                                    }

                                    // note a metadata entry must terminate with \r\n

                                    if ((i+1 == length) || (ch[i] == '\n'))
                                    {
                                        string value = entry.MetaInfo.Substring(start, (ch[i-1] == '\r'? (i-1):(i+1)) - start);

                                        if (value.Length == 0 && cacheEntry.EntryMetadata == null)
                                        {
                                            // done with headers, prepare for system metadata
                                            cacheEntry.EntryMetadata = sc;
                                            sc = new StringCollection();
                                        }
                                        else
                                        {
                                            //WinInet specific block!!
                                            // HACK: if we are parsing system metadata and have found our hack,
                                            // then convert it to a sparse entry type (entry.Info.EntryType & _WinInetCache.EntryType.Sparse)
                                            if (cacheEntry.EntryMetadata != null && value.StartsWith(c_SPARSE_ENTRY_HACK, StringComparison.Ordinal))
                                                cacheEntry.IsPartialEntry = true;
                                            else
                                                sc.Add(value);
                                        }
                                        start = i+1;
                                    }
                                }
                            }
                            if (cacheEntry.EntryMetadata == null )
                                {cacheEntry.EntryMetadata = sc;}
                            else
                                {cacheEntry.SystemMetadata = sc;}
                        }
                    }

                    result = new ReadStream(entry, handle, async);

                }
                else {
                    if (handle != null) {
                        handle.Close();
                    }

                    cacheEntry = new RequestCacheEntry();
                    cacheEntry.IsPrivateEntry = IsPrivateCache;

                    if (entry.Error != _WinInetCache.Status.FileNotFound)
                    {
                        if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_lookup_failed, "WinInetCache.Retrieve()", new Win32Exception((int)entry.Error).Message));
                        if(Logging.On)Logging.Exit(Logging.RequestCache, "WinInetCache.Retrieve()");
                        if(isThrow)
                        {
                            Win32Exception win32Exception = new Win32Exception((int)entry.Error);
                            throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, win32Exception.Message), win32Exception);
                        }
                        return null;
                    }
                }
            }
            catch (Exception exception) {
                if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
                    throw;
                }

                if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_exception, "WinInetCache.Retrieve()", exception.ToString()));
                if(Logging.On)Logging.Exit(Logging.RequestCache, "WinInetCache.Retrieve()");

                if (handle != null) {
                    handle.Close();
                }
                result.Close();
                result = Stream.Null;
                cacheEntry = new RequestCacheEntry();
                cacheEntry.IsPrivateEntry = IsPrivateCache;
                if (isThrow)
                {
                    throw;
                }
                return null;
            }
            if(Logging.On)Logging.Exit(Logging.RequestCache, "WinInetCache.Retrieve()", "Status = " + entry.Error.ToString());
            return result;
        }
        /// <summary>
        /// <para>
        /// Removes an item from the IE cache. Throws Win32Excpetion if failed
        /// </para>
        /// </summary>
        internal override void Remove(string key) {

            if (key == null) {
                throw new ArgumentNullException("key");
            }

            if (!CanWrite)
            {
                if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_operation_failed_with_error, "WinInetCache.Remove()", SR.GetString(SR.net_cache_access_denied, "Write")));
                return ;
            }

            _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength);

            if (_WinInetCache.Remove(entry) != _WinInetCache.Status.Success && entry.Error != _WinInetCache.Status.FileNotFound) {
                Win32Exception win32Exception = new Win32Exception((int)entry.Error);
                if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_cannot_remove, "WinInetCache.Remove()", key, win32Exception.Message));
                throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, win32Exception.Message), win32Exception);
            }

            if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_key_status, "WinInetCache.Remove(), ", key, entry.Error.ToString()));
        }