484 lines
16 KiB
C#
484 lines
16 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: CarotDAV.OleStream
|
|
// Assembly: CarotDAV, Version=1.13.2.18337, Culture=neutral, PublicKeyToken=null
|
|
// MVID: C31F2651-A4A8-4D09-916A-8C6106F5E7C8
|
|
// Assembly location: F:\Eigene Dateien\Dropbox\portable Collection\Progs\CarotDAV\CarotDAV.exe
|
|
|
|
using Microsoft.VisualBasic.CompilerServices;
|
|
using Rei.Fs;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
using System.Runtime.InteropServices.ComTypes;
|
|
using System.Threading;
|
|
|
|
namespace CarotDAV
|
|
{
|
|
[ClassInterface(ClassInterfaceType.None)]
|
|
public class OleStream : IStream, IDisposable
|
|
{
|
|
private static DateTime win32timeorigin = new DateTime(1601, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
private const int E_NOTIMPL = -2147483647;
|
|
private const int E_PENDING = -2147483638;
|
|
private const int STG_E_ACCESSDENIED = -2147287035;
|
|
private const int STG_E_INVALIDFLAG = -2147286785;
|
|
private const int S_OK = 0;
|
|
private const int S_FALSE = 1;
|
|
private const int STG_E_TERMINATED = -2147286526;
|
|
private const int STG_E_READFAULT = -2147287010;
|
|
private const int STG_E_REVERTED = -2147286782;
|
|
private const int STG_E_INVALIDPOINTER = -2147287031;
|
|
private const int STG_E_NOMOREFILES = -2147287022;
|
|
private const int STG_E_FILENOTFOUND = -2147287038;
|
|
private const int STG_E_INCOMPLETE = -2147286527;
|
|
private static int pOpenCount;
|
|
private Stream pStream;
|
|
private string pName;
|
|
private ResourceInfo pResourceInfo;
|
|
private int pSeekPointer;
|
|
private int pDisposed;
|
|
private bool pFinished;
|
|
private System.Runtime.InteropServices.ComTypes.STATSTG pStatstg;
|
|
private object pLock;
|
|
private FsBase pClient;
|
|
private ErrorPromptManager pErrorManager;
|
|
private List<OleStream> pClonelist;
|
|
|
|
public static int OpenCount
|
|
{
|
|
get
|
|
{
|
|
return OleStream.pOpenCount;
|
|
}
|
|
}
|
|
|
|
public event EventHandler<ExceptionOccurredEventArgs> ExceptionOccurred;
|
|
|
|
public OleStream(ResourceInfo ri, string name, FsBase client, ErrorPromptManager errormanager)
|
|
{
|
|
this.pDisposed = 0;
|
|
this.pResourceInfo = ri;
|
|
this.pName = name;
|
|
this.pStream = (Stream) null;
|
|
this.pSeekPointer = 0;
|
|
this.pFinished = false;
|
|
this.pLock = RuntimeHelpers.GetObjectValue(new object());
|
|
this.pClient = client;
|
|
this.pErrorManager = errormanager;
|
|
this.pClonelist = new List<OleStream>();
|
|
this.pStatstg.type = 2;
|
|
this.pStatstg.pwcsName = this.pName;
|
|
this.pStatstg.cbSize = this.pResourceInfo.Size;
|
|
this.pStatstg.mtime = this.ToFileTime(this.pResourceInfo.LastModifiedTime);
|
|
this.pStatstg.ctime = this.ToFileTime(this.pResourceInfo.CreationTime);
|
|
this.pStatstg.atime = this.ToFileTime(this.pResourceInfo.LastAccessTime);
|
|
this.pStatstg.grfMode = 0;
|
|
this.pStatstg.grfLocksSupported = 0;
|
|
this.pStatstg.clsid = Guid.Empty;
|
|
this.pStatstg.grfStateBits = 0;
|
|
this.pStatstg.reserved = 0;
|
|
}
|
|
|
|
public FsBase Client
|
|
{
|
|
get
|
|
{
|
|
return this.pClient;
|
|
}
|
|
}
|
|
|
|
[DebuggerStepThrough]
|
|
public void IStreamLockRegion(long libOffset, long cb, int dwLockType)
|
|
{
|
|
Marshal.ThrowExceptionForHR(-2147483647);
|
|
}
|
|
|
|
[DebuggerStepThrough]
|
|
public void IStreamUnlockRegion(long libOffset, long cb, int dwLockType)
|
|
{
|
|
Marshal.ThrowExceptionForHR(-2147483647);
|
|
}
|
|
|
|
[DebuggerStepThrough]
|
|
public void IStreamWrite(byte[] pv, int cb, IntPtr pcbWritten)
|
|
{
|
|
Marshal.ThrowExceptionForHR(-2147483647);
|
|
}
|
|
|
|
[DebuggerStepThrough]
|
|
public void IStreamCommit(int grfCommitFlags)
|
|
{
|
|
Marshal.ThrowExceptionForHR(-2147483647);
|
|
}
|
|
|
|
[DebuggerStepThrough]
|
|
public void IStreamRevert()
|
|
{
|
|
Marshal.ThrowExceptionForHR(-2147483647);
|
|
}
|
|
|
|
[DebuggerStepThrough]
|
|
public void IStreamSeek(long dlibMove, int dwOrigin, IntPtr plibNewPosition)
|
|
{
|
|
Marshal.ThrowExceptionForHR(-2147483647);
|
|
}
|
|
|
|
[DebuggerStepThrough]
|
|
public void IStreamSetSize(long libNewSize)
|
|
{
|
|
Marshal.ThrowExceptionForHR(-2147483647);
|
|
}
|
|
|
|
[DebuggerStepThrough]
|
|
public void IStreamCopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
|
|
{
|
|
Marshal.ThrowExceptionForHR(-2147483647);
|
|
}
|
|
|
|
public void IStreamClone(ref IStream ppstm)
|
|
{
|
|
OleStream oleStream = new OleStream(this.pResourceInfo, this.pName, this.pClient, this.pErrorManager);
|
|
oleStream.pLock = RuntimeHelpers.GetObjectValue(this.pLock);
|
|
oleStream.ExceptionOccurredEvent = (EventHandler<ExceptionOccurredEventArgs>) this.ExceptionOccurredEvent.Clone();
|
|
this.pClonelist.Add(oleStream);
|
|
ppstm = (IStream) oleStream;
|
|
}
|
|
|
|
public void IStreamStat(ref System.Runtime.InteropServices.ComTypes.STATSTG statstg, int grfStatFlag)
|
|
{
|
|
switch (grfStatFlag)
|
|
{
|
|
case 0:
|
|
statstg.pwcsName = this.pStatstg.pwcsName;
|
|
goto case 1;
|
|
case 1:
|
|
statstg.type = this.pStatstg.type;
|
|
statstg.cbSize = this.pStatstg.cbSize;
|
|
statstg.mtime = this.pStatstg.mtime;
|
|
statstg.ctime = this.pStatstg.ctime;
|
|
statstg.atime = this.pStatstg.atime;
|
|
statstg.grfMode = 0;
|
|
statstg.grfLocksSupported = 0;
|
|
statstg.clsid = Guid.Empty;
|
|
statstg.grfStateBits = 0;
|
|
statstg.reserved = 0;
|
|
break;
|
|
case 2:
|
|
Marshal.ThrowExceptionForHR(-2147286785);
|
|
goto case 1;
|
|
default:
|
|
Marshal.ThrowExceptionForHR(-2147286785);
|
|
goto case 1;
|
|
}
|
|
}
|
|
|
|
public void IStreamRead(byte[] pv, int cb, IntPtr pcbRead)
|
|
{
|
|
int num1 = 0;
|
|
object pLock = this.pLock;
|
|
ObjectFlowControl.CheckForSyncLockOnValueType(pLock);
|
|
Monitor.Enter(pLock);
|
|
try
|
|
{
|
|
if (this.pFinished)
|
|
{
|
|
if (!(pcbRead != IntPtr.Zero))
|
|
return;
|
|
Marshal.WriteInt32(pcbRead, num1);
|
|
}
|
|
else
|
|
{
|
|
if (Thread.VolatileRead(ref this.pDisposed) == 1)
|
|
{
|
|
if (pcbRead != IntPtr.Zero)
|
|
Marshal.WriteInt32(pcbRead, num1);
|
|
Marshal.ThrowExceptionForHR(-2147286526);
|
|
}
|
|
int retryminutes = 1;
|
|
label_9:
|
|
while (this.pStream == null)
|
|
{
|
|
try
|
|
{
|
|
FsBase pClient = this.pClient;
|
|
ResourceId id = this.pResourceInfo.Id;
|
|
long start = 0;
|
|
long length = -1;
|
|
this.pStream = pClient.OpenRead(id, ref start, ref length);
|
|
this.pSeekPointer = 0;
|
|
}
|
|
catch (Exception ex1)
|
|
{
|
|
ProjectData.SetProjectError(ex1);
|
|
Exception ex2 = ex1;
|
|
this.pStream = (Stream) null;
|
|
if (pcbRead != IntPtr.Zero)
|
|
Marshal.WriteInt32(pcbRead, num1);
|
|
ErrorAction errorAction;
|
|
if (this.pErrorManager.IgnoreAll())
|
|
{
|
|
errorAction = ErrorAction.Ignore;
|
|
}
|
|
else
|
|
{
|
|
ExceptionOccurredEventArgs e = new ExceptionOccurredEventArgs("Error occurred during downloading file.", this.pResourceInfo.Id.ToString(), ErrorPromptType.IgnoreAllIgnoreRetryCancel, ex2, retryminutes);
|
|
EventHandler<ExceptionOccurredEventArgs> exceptionOccurredEvent = this.ExceptionOccurredEvent;
|
|
if (exceptionOccurredEvent != null)
|
|
exceptionOccurredEvent((object) this, e);
|
|
this.pErrorManager.RegisterAction(e.Result);
|
|
errorAction = e.Result.Action;
|
|
}
|
|
switch (errorAction)
|
|
{
|
|
case ErrorAction.Ignore:
|
|
this.Dispose();
|
|
throw new COMException("", 1);
|
|
case ErrorAction.Retry:
|
|
ProjectData.ClearProjectError();
|
|
continue;
|
|
case ErrorAction.AutoRetry:
|
|
checked { retryminutes *= 2; }
|
|
ProjectData.ClearProjectError();
|
|
continue;
|
|
case ErrorAction.Cancel:
|
|
Marshal.ThrowExceptionForHR(-2147286526);
|
|
ProjectData.ClearProjectError();
|
|
break;
|
|
default:
|
|
throw;
|
|
}
|
|
}
|
|
Interlocked.Increment(ref OleStream.pOpenCount);
|
|
break;
|
|
}
|
|
while (num1 < cb)
|
|
{
|
|
int num2;
|
|
try
|
|
{
|
|
num2 = this.pStream.Read(pv, num1, checked (cb - num1));
|
|
}
|
|
catch (Exception ex1)
|
|
{
|
|
ProjectData.SetProjectError(ex1);
|
|
Exception ex2 = ex1;
|
|
try
|
|
{
|
|
this.pStream.Close();
|
|
}
|
|
catch (Exception ex3)
|
|
{
|
|
ProjectData.SetProjectError(ex3);
|
|
ProjectData.ClearProjectError();
|
|
}
|
|
Interlocked.Decrement(ref OleStream.pOpenCount);
|
|
this.pStream = (Stream) null;
|
|
if (pcbRead != IntPtr.Zero)
|
|
Marshal.WriteInt32(pcbRead, num1);
|
|
ErrorAction errorAction;
|
|
if (this.pErrorManager.IgnoreAll())
|
|
{
|
|
errorAction = ErrorAction.Ignore;
|
|
}
|
|
else
|
|
{
|
|
ExceptionOccurredEventArgs e = new ExceptionOccurredEventArgs("Error occurred during downloading file.", this.pResourceInfo.Id.ToString(), ErrorPromptType.IgnoreAllIgnoreRetryCancel, ex2, retryminutes);
|
|
EventHandler<ExceptionOccurredEventArgs> exceptionOccurredEvent = this.ExceptionOccurredEvent;
|
|
if (exceptionOccurredEvent != null)
|
|
exceptionOccurredEvent((object) this, e);
|
|
this.pErrorManager.RegisterAction(e.Result);
|
|
errorAction = e.Result.Action;
|
|
}
|
|
switch (errorAction)
|
|
{
|
|
case ErrorAction.Ignore:
|
|
this.Dispose();
|
|
throw new COMException("", 1);
|
|
case ErrorAction.Retry:
|
|
ProjectData.ClearProjectError();
|
|
goto label_9;
|
|
case ErrorAction.AutoRetry:
|
|
checked { retryminutes *= 2; }
|
|
ProjectData.ClearProjectError();
|
|
goto label_9;
|
|
case ErrorAction.Cancel:
|
|
Marshal.ThrowExceptionForHR(-2147286526);
|
|
ProjectData.ClearProjectError();
|
|
break;
|
|
default:
|
|
throw;
|
|
}
|
|
}
|
|
checked { num1 += num2; }
|
|
this.pSeekPointer = checked (this.pSeekPointer + num2);
|
|
if ((long) this.pSeekPointer != this.pStatstg.cbSize)
|
|
{
|
|
if (this.pStatstg.cbSize < 0L)
|
|
{
|
|
if (num2 == 0)
|
|
goto label_45;
|
|
}
|
|
if (num2 == 0)
|
|
{
|
|
if ((long) this.pSeekPointer < this.pStatstg.cbSize)
|
|
{
|
|
ErrorAction errorAction;
|
|
if (this.pErrorManager.IgnoreAll())
|
|
{
|
|
errorAction = ErrorAction.Ignore;
|
|
}
|
|
else
|
|
{
|
|
ExceptionOccurredEventArgs e = new ExceptionOccurredEventArgs("Error occurred during downloading file.", this.pResourceInfo.Id.ToString(), ErrorPromptType.IgnoreAllIgnoreRetryCancel, (Exception) new IOException("unexpected close of stream"), retryminutes);
|
|
EventHandler<ExceptionOccurredEventArgs> exceptionOccurredEvent = this.ExceptionOccurredEvent;
|
|
if (exceptionOccurredEvent != null)
|
|
exceptionOccurredEvent((object) this, e);
|
|
this.pErrorManager.RegisterAction(e.Result);
|
|
errorAction = e.Result.Action;
|
|
}
|
|
switch (errorAction)
|
|
{
|
|
case ErrorAction.Ignore:
|
|
this.Dispose();
|
|
throw new COMException("", 1);
|
|
case ErrorAction.Retry:
|
|
goto label_9;
|
|
case ErrorAction.AutoRetry:
|
|
checked { retryminutes *= 2; }
|
|
goto label_9;
|
|
case ErrorAction.Cancel:
|
|
Marshal.ThrowExceptionForHR(-2147286526);
|
|
continue;
|
|
default:
|
|
throw new Exception();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Marshal.ThrowExceptionForHR(-2147287010);
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
continue;
|
|
}
|
|
label_45:
|
|
try
|
|
{
|
|
this.pStream.Close();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ProjectData.SetProjectError(ex);
|
|
ProjectData.ClearProjectError();
|
|
}
|
|
Interlocked.Decrement(ref OleStream.pOpenCount);
|
|
this.pStream = (Stream) null;
|
|
this.pFinished = true;
|
|
break;
|
|
}
|
|
if (!(pcbRead != IntPtr.Zero))
|
|
return;
|
|
Marshal.WriteInt32(pcbRead, num1);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Monitor.Exit(pLock);
|
|
}
|
|
}
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (Interlocked.CompareExchange(ref this.pDisposed, 1, 0) != 0 || !disposing)
|
|
return;
|
|
object pLock = this.pLock;
|
|
ObjectFlowControl.CheckForSyncLockOnValueType(pLock);
|
|
Monitor.Enter(pLock);
|
|
try
|
|
{
|
|
if (this.pStream != null)
|
|
{
|
|
try
|
|
{
|
|
this.pStream.Close();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ProjectData.SetProjectError(ex);
|
|
ProjectData.ClearProjectError();
|
|
}
|
|
Interlocked.Decrement(ref OleStream.pOpenCount);
|
|
this.pStream = (Stream) null;
|
|
}
|
|
List<OleStream>.Enumerator enumerator;
|
|
try
|
|
{
|
|
enumerator = this.pClonelist.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
OleStream current = enumerator.Current;
|
|
try
|
|
{
|
|
current.Dispose();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ProjectData.SetProjectError(ex);
|
|
ProjectData.ClearProjectError();
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
enumerator.Dispose();
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Monitor.Exit(pLock);
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
this.Dispose(true);
|
|
GC.SuppressFinalize((object) this);
|
|
}
|
|
|
|
~OleStream()
|
|
{
|
|
this.Dispose(false);
|
|
// ISSUE: explicit finalizer call
|
|
base.Finalize();
|
|
}
|
|
|
|
private System.Runtime.InteropServices.ComTypes.FILETIME ToFileTime(DateTime time)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(DateTime.Compare(time, OleStream.win32timeorigin) >= 0 ? time.ToFileTime() : 0L);
|
|
System.Runtime.InteropServices.ComTypes.FILETIME filetime;
|
|
filetime.dwHighDateTime = BitConverter.ToInt32(bytes, 4);
|
|
filetime.dwLowDateTime = BitConverter.ToInt32(bytes, 0);
|
|
return filetime;
|
|
}
|
|
|
|
private enum STATFLAG
|
|
{
|
|
STATFLAG_DEFAULT,
|
|
STATFLAG_NONAME,
|
|
STATFLAG_NOOPEN,
|
|
}
|
|
|
|
[Flags]
|
|
private enum LOCKTYPE
|
|
{
|
|
LOCK_WRITE = 1,
|
|
LOCK_EXCLUSIVE = 2,
|
|
LOCK_ONLYONCE = 4,
|
|
}
|
|
}
|
|
}
|