Files
App-Installer-For-Windows-8…/PriFileFormat/ComStreamWrapper.cs
Bruce d1813637c5 Organized the project files.
And also fixed some bugs.
2025-12-08 16:06:13 +08:00

123 lines
2.6 KiB
C#

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace PriFileFormat
{
public class ComStreamWrapper: Stream
{
private IStream comStream;
public ComStreamWrapper (IStream stream)
{
if (stream == null)
throw new ArgumentNullException ("stream");
comStream = stream;
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override long Length
{
get
{
System.Runtime.InteropServices.ComTypes.STATSTG stat;
comStream.Stat (out stat, 1); // STATFLAG_NONAME = 1
return stat.cbSize;
}
}
public override long Position
{
get
{
IntPtr posPtr = Marshal.AllocHGlobal (sizeof (long));
try
{
// SEEK_CUR = 1
comStream.Seek (0, 1, posPtr);
return Marshal.ReadInt64 (posPtr);
}
finally
{
Marshal.FreeHGlobal (posPtr);
}
}
set
{
// SEEK_SET = 0
comStream.Seek (value, 0, IntPtr.Zero);
}
}
public override void Flush ()
{
comStream.Commit (0); // STGC_DEFAULT = 0
}
public override int Read (byte [] buffer, int offset, int count)
{
if (offset != 0)
throw new NotSupportedException ("Offset != 0 not supported in this wrapper.");
IntPtr bytesRead = Marshal.AllocHGlobal (sizeof (int));
try
{
comStream.Read (buffer, count, bytesRead);
return Marshal.ReadInt32 (bytesRead);
}
finally
{
Marshal.FreeHGlobal (bytesRead);
}
}
public override void Write (byte [] buffer, int offset, int count)
{
if (offset != 0)
throw new NotSupportedException ("Offset != 0 not supported in this wrapper.");
IntPtr bytesWritten = Marshal.AllocHGlobal (sizeof (int));
try
{
comStream.Write (buffer, count, bytesWritten);
}
finally
{
Marshal.FreeHGlobal (bytesWritten);
}
}
public override long Seek (long offset, SeekOrigin origin)
{
int originInt = 0;
switch (origin)
{
case SeekOrigin.Begin: originInt = 0; break; // STREAM_SEEK_SET
case SeekOrigin.Current: originInt = 1; break; // STREAM_SEEK_CUR
case SeekOrigin.End: originInt = 2; break; // STREAM_SEEK_END
}
IntPtr posPtr = Marshal.AllocHGlobal (sizeof (long));
try
{
comStream.Seek (offset, originInt, posPtr);
return Marshal.ReadInt64 (posPtr);
}
finally
{
Marshal.FreeHGlobal (posPtr);
}
}
public override void SetLength (long value)
{
comStream.SetSize (value);
}
~ComStreamWrapper () { comStream = null;}
}
}