Ejemplo n.º 1
0
        protected override int ProcessIncoming(NetContext context, Connection connection, Stream incomingBuffer)
        {
            int len = FindHeadersLength(incomingBuffer);
            if (len <= 0) return 0;

            incomingBuffer.Position = 0;
            int extraConsumed;
            if (len < NetContext.BufferSize)
            {
                byte[] buffer = null;
                try
                {
                    buffer = context.GetBuffer();
                    NetContext.Fill(incomingBuffer, buffer, len);
                    using (var ms = new MemoryStream(buffer, 0, len))
                    {
                        extraConsumed = ProcessHeadersAndUpgrade(context, connection, ms, incomingBuffer, len);
                    }
                }
                finally
                {
                    context.Recycle(buffer);
                }
            }
            else
            {
                using (var ss = new SubStream(incomingBuffer, len))
                {
                    extraConsumed = ProcessHeadersAndUpgrade(context, connection, ss, incomingBuffer, len);
                }
            }
            if (extraConsumed < 0) return 0; // means: wasn't usable (yet)

            return len + extraConsumed;
        }
Ejemplo n.º 2
0
 internal bool TryOpenFile(string path, out Stream stream)
 {
     if (_files.ContainsKey(path))
     {
         FileRecord file = _files[path];
         stream = new SubStream(_fileStream, file.Start, file.Length);
         return true;
     }
     stream = null;
     return false;
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a new stream that contains the XVA image.
        /// </summary>
        /// <returns>The new stream.</returns>
        public override SparseStream Build()
        {
            TarFileBuilder tarBuilder = new TarFileBuilder();

            int[] diskIds;

            string ovaFileContent = GenerateOvaXml(out diskIds);
            tarBuilder.AddFile("ova.xml", Encoding.ASCII.GetBytes(ovaFileContent));

            int diskIdx = 0;
            foreach (var diskRec in _disks)
            {
                SparseStream diskStream = diskRec.Second;
                List<StreamExtent> extents = new List<StreamExtent>(diskStream.Extents);

                int lastChunkAdded = -1;
                foreach (StreamExtent extent in extents)
                {
                    int firstChunk = (int)(extent.Start / Sizes.OneMiB);
                    int lastChunk = (int)((extent.Start + extent.Length - 1) / Sizes.OneMiB);

                    for (int i = firstChunk; i <= lastChunk; ++i)
                    {
                        if (i != lastChunkAdded)
                        {
                            HashAlgorithm hashAlg = new SHA1Managed();
                            Stream chunkStream;

                            long diskBytesLeft = diskStream.Length - (i * Sizes.OneMiB);
                            if (diskBytesLeft < Sizes.OneMiB)
                            {
                                chunkStream = new ConcatStream(
                                    Ownership.Dispose,
                                    new SubStream(diskStream, i * Sizes.OneMiB, diskBytesLeft),
                                    new ZeroStream(Sizes.OneMiB - diskBytesLeft));
                            }
                            else
                            {
                                chunkStream = new SubStream(diskStream, i * Sizes.OneMiB, Sizes.OneMiB);
                            }

                            HashStream chunkHashStream = new HashStream(chunkStream, Ownership.Dispose, hashAlg);

                            tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], i), chunkHashStream);
                            tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], i), new ChecksumStream(hashAlg));

                            lastChunkAdded = i;
                        }
                    }
                }

                // Make sure the last chunk is present, filled with zero's if necessary
                int lastActualChunk = (int)((diskStream.Length - 1) / Sizes.OneMiB);
                if (lastChunkAdded < lastActualChunk)
                {
                    HashAlgorithm hashAlg = new SHA1Managed();
                    Stream chunkStream = new ZeroStream(Sizes.OneMiB);
                    HashStream chunkHashStream = new HashStream(chunkStream, Ownership.Dispose, hashAlg);
                    tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], lastActualChunk), chunkHashStream);
                    tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], lastActualChunk), new ChecksumStream(hashAlg));
                }

                ++diskIdx;
            }

            return tarBuilder.Build();
        }
Ejemplo n.º 4
0
        private void Process(System.Net.HttpListenerContext obj)
        {
            Stream org = null;

            try
            {

                bool fname = false;
                string[] dta = obj.Request.RawUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                if (dta.Length < 3)
                    return;
                string cmd = dta[0].ToLower();
                string user = dta[1];
                string arg = dta[2];
                string fullname;
                int userid = 0;
                int.TryParse(user, out userid);
                VideoLocal loc=null;
                if (cmd == "videolocal")
                {
                    int sid = 0;
                    int.TryParse(arg, out sid);
                    if (sid == 0)
                    {
                        obj.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        obj.Response.StatusDescription = "Stream Id missing.";
                        return;
                    }
                    VideoLocalRepository rep = new VideoLocalRepository();
                    loc = rep.GetByID(sid);
                    if (loc == null)
                    {
                        obj.Response.StatusCode = (int)HttpStatusCode.NotFound;
                        obj.Response.StatusDescription = "Stream Id not found.";
                        return;

                    }
                    fullname = loc.FullServerPath;
                }
                else if (cmd == "file")
                {
                    fullname = Base64DecodeUrl(arg);

                }
                else
                {
                    obj.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    obj.Response.StatusDescription = "Not know command";
                    return;
                }

                bool range = false;

                try
                {
                    if (!File.Exists(fullname))
                    {
                        obj.Response.StatusCode = (int)HttpStatusCode.NotFound;
                        obj.Response.StatusDescription = "File '" + fullname + "' not found.";
                        return;
                    }

                }
                catch (Exception)
                {
                    obj.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    obj.Response.StatusDescription = "Unable to access File '" + fullname + "'.";
                    return;
                }
                obj.Response.ContentType = GetMime(fullname);
                obj.Response.AddHeader("Accept-Ranges", "bytes");
                obj.Response.AddHeader("X-Plex-Protocol", "1.0");
                if (obj.Request.HttpMethod == "OPTIONS")
                {
                    obj.Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, HEAD");
                    obj.Response.AddHeader("Access-Control-Max-Age", "1209600");
                    obj.Response.AddHeader("Access-Control-Allow-Headers",
                        "accept, x-plex-token, x-plex-client-identifier, x-plex-username, x-plex-product, x-plex-device, x-plex-platform, x-plex-platform-version, x-plex-version, x-plex-device-name");
                    obj.Response.AddHeader("Cache-Control", "no-cache");
                    obj.Response.ContentType = "text/plain";
                    return;
                }
                string rangevalue = null;
                if (obj.Request.Headers.AllKeys.Contains("Range"))
                    rangevalue = obj.Request.Headers["Range"].Replace("bytes=", string.Empty).Trim();
                if (obj.Request.Headers.AllKeys.Contains("range"))
                    rangevalue = obj.Request.Headers["range"].Replace("bytes=", string.Empty).Trim();

                if (obj.Request.HttpMethod != "HEAD")
                {
                    org = new FileStream(fullname, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    long totalsize = org.Length;
                    long start = 0;
                    long end = 0;
                    if (!string.IsNullOrEmpty(rangevalue))
                    {
                        range = true;
                        string[] split = rangevalue.Split('-');
                        if (split.Length == 2)
                        {
                            if (string.IsNullOrEmpty(split[0]) && !string.IsNullOrEmpty(split[1]))
                            {
                                long e = long.Parse(split[1]);
                                start = totalsize - e;
                                end = totalsize - 1;
                            }
                            else if (!string.IsNullOrEmpty(split[0]) && string.IsNullOrEmpty(split[1]))
                            {
                                start = long.Parse(split[0]);
                                end = totalsize - 1;
                            }
                            else if (!string.IsNullOrEmpty(split[0]) && !string.IsNullOrEmpty(split[1]))
                            {
                                start = long.Parse(split[0]);
                                end = long.Parse(split[1]);
                                if (start > totalsize - 1)
                                    start = totalsize - 1;
                                if (end > totalsize - 1)
                                    end = totalsize - 1;
                            }
                            else
                            {
                                start = 0;
                                end = totalsize - 1;
                            }
                        }
                    }
                    SubStream outstream;
                    if (range)
                    {
                        obj.Response.StatusCode = (int) HttpStatusCode.PartialContent;
                        obj.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + totalsize);
                        outstream = new SubStream(org, start, end - start + 1);
                        obj.Response.ContentLength64 = end - start + 1;
                    }
                    else
                    {
                        outstream=new SubStream(org,0,totalsize);
                        obj.Response.ContentLength64 = totalsize;
                        obj.Response.StatusCode = (int) HttpStatusCode.OK;
                    }
                    if ((userid != 0) && (loc != null))
                    {
                        outstream.CrossPosition = (long) ((double) totalsize*WatchedThreshold);
                        outstream.CrossPositionCrossed += (a) =>
                        {
                            Task.Factory.StartNew(() =>
                            {
                                loc.ToggleWatchedStatus(true, userid);
                            }, new CancellationToken(), TaskCreationOptions.LongRunning, TaskScheduler.Default);
                        };
                    }
                    obj.Response.SendChunked = false;
                    outstream.CopyTo(obj.Response.OutputStream);
                    obj.Response.OutputStream.Close();
                    outstream.Close();
                }
                else
                {
                    obj.Response.SendChunked = false;
                    obj.Response.StatusCode = (int)HttpStatusCode.OK;
                    obj.Response.ContentLength64 = new FileInfo(fullname).Length;
                    obj.Response.KeepAlive = false;
                    obj.Response.OutputStream.Close();
                }
            }
            catch (HttpListenerException e)
            {
            }
            catch (Exception e)
            {
                logger.Error(e.ToString);
            }
            finally
            {
                if (org != null)
                    org.Close();
                if ((obj != null) && (obj.Response != null) && (obj.Response.OutputStream != null))
                    obj.Response.OutputStream.Close();
            }
        }
Ejemplo n.º 5
0
        private void LoadRootDirectory()
        {
            Stream fatStream;
            if (_type != FatType.Fat32)
            {
                fatStream = new SubStream(_data, (_bpbRsvdSecCnt + (_bpbNumFATs * _bpbFATSz16)) * _bpbBytesPerSec, _bpbRootEntCnt * 32);
            }
            else
            {
                fatStream = new ClusterStream(this, FileAccess.ReadWrite, _bpbRootClus, uint.MaxValue);
            }

            _rootDir = new Directory(this, fatStream);
        }
Ejemplo n.º 6
0
 private void LoadDescriptor(Stream s)
 {
     s.Position = 0;
     byte[] header = Utilities.ReadFully(s, (int)Math.Min(Sizes.Sector, s.Length));
     if (header.Length < Sizes.Sector || Utilities.ToUInt32LittleEndian(header, 0) != HostedSparseExtentHeader.VmdkMagicNumber)
     {
         s.Position = 0;
         _descriptor = new DescriptorFile(s);
         if (_access != FileAccess.Read)
         {
             _descriptor.ContentId = (uint)_rng.Next();
             s.Position = 0;
             _descriptor.Write(s);
             s.SetLength(s.Position);
         }
     }
     else
     {
         // This is a sparse disk extent, hopefully with embedded descriptor...
         HostedSparseExtentHeader hdr = HostedSparseExtentHeader.Read(header, 0);
         if (hdr.DescriptorOffset != 0)
         {
             Stream descriptorStream = new SubStream(s, hdr.DescriptorOffset * Sizes.Sector, hdr.DescriptorSize * Sizes.Sector);
             _descriptor = new DescriptorFile(descriptorStream);
             if (_access != FileAccess.Read)
             {
                 _descriptor.ContentId = (uint)_rng.Next();
                 descriptorStream.Position = 0;
                 _descriptor.Write(descriptorStream);
                 byte[] blank = new byte[descriptorStream.Length - descriptorStream.Position];
                 descriptorStream.Write(blank, 0, blank.Length);
             }
         }
     }
 }
Ejemplo n.º 7
0
        private Stream OpenChunkStream(int chunk)
        {
            int targetUncompressed = _chunkSize;
            if (chunk == _chunkLength.Length - 1)
            {
                targetUncompressed = (int)(Length - _position);
            }

            Stream rawChunkStream = new SubStream(_baseStream, _offsetDelta + _chunkOffsets[chunk], _chunkLength[chunk]);
            if ((_header.Flags & ResourceFlags.Compressed) != 0 && _chunkLength[chunk] != targetUncompressed)
            {
                if (_lzxCompression)
                {
                    return new LzxStream(rawChunkStream, 15, E8DecodeFileSize);
                }
                else
                {
                    return new XpressStream(rawChunkStream, targetUncompressed);
                }
            }
            else
            {
                return rawChunkStream;
            }
        }
Ejemplo n.º 8
0
        private void Process(System.Net.HttpListenerContext obj)
        {
            Stream org = null;

            try
            {
                bool fname = false;
                string[] dta = obj.Request.RawUrl.Split(new char[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
                if (dta.Length < 4)
                    return;
                string cmd = dta[0].ToLower();
                string user = dta[1];
                string aw = dta[2];
                string arg = dta[3];
                string fullname = string.Empty;
                int userid = 0;
                int autowatch = 0;
                int.TryParse(user, out userid);
                int.TryParse(aw, out autowatch);
                VideoLocal loc = null;
                IFile file = null;
                if (cmd == "videolocal")
                {
                    int sid = 0;
                    int.TryParse(arg, out sid);
                    if (sid == 0)
                    {
                        obj.Response.StatusCode = (int) HttpStatusCode.BadRequest;
                        obj.Response.StatusDescription = "Stream Id missing.";
                        return;
                    }
                    loc = RepoFactory.VideoLocal.GetByID(sid);
                    if (loc == null)
                    {
                        obj.Response.StatusCode = (int)HttpStatusCode.NotFound;
                        obj.Response.StatusDescription = "Stream Id not found.";
                        return;
                    }
            #if DEBUG_STREAM
                    if (loc.VideoLocalID == 6393488934891)
                    {
                        FileSystemResult<IFileSystem> ff = CloudFileSystemPluginFactory.Instance.List.FirstOrDefault(a => a.Name == "Local File System")?.Init("", null, null);
                        if (ff == null || !ff.IsOk)
                            throw new Exception(ff?.Error ?? "Error Opening Local Filesystem");
                        FileSystemResult<IObject> o=ff.Result.Resolve(@"C:\test\unsort\[FTV-Wasurenai] 11eyes - 01 [1280x720 BD H264] [07238189].mkv");
                        if (o.IsOk)
                            file = (IFile) o.Result;
                    }
                    else
            #endif
                        file = loc.GetBestFileLink();
                    if (file == null)
                    {
                        obj.Response.StatusCode = (int) HttpStatusCode.NotFound;
                        obj.Response.StatusDescription = "Stream Id not found.";
                        return;
                    }
                    fullname = file.FullName;
                }
                else if (cmd == "file")
                {
                    fullname = Base64DecodeUrl(arg);
                    file = VideoLocal.ResolveFile(fullname);
                    if (file == null)
                    {
                        obj.Response.StatusCode = (int) HttpStatusCode.NotFound;
                        obj.Response.StatusDescription = "File not found.";
                        return;
                    }
                }
                else
                {
                    obj.Response.StatusCode = (int) HttpStatusCode.BadRequest;
                    obj.Response.StatusDescription = "Not know command";
                    return;
                }

                bool range = false;
                obj.Response.ContentType = GetMime(fullname);
                obj.Response.AddHeader("Accept-Ranges", "bytes");
                obj.Response.AddHeader("X-Plex-Protocol", "1.0");
                if (obj.Request.HttpMethod == "OPTIONS")
                {
                    obj.Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, HEAD");
                    obj.Response.AddHeader("Access-Control-Max-Age", "1209600");
                    obj.Response.AddHeader("Access-Control-Allow-Headers",
                        "accept, x-plex-token, x-plex-client-identifier, x-plex-username, x-plex-product, x-plex-device, x-plex-platform, x-plex-platform-version, x-plex-version, x-plex-device-name");
                    obj.Response.AddHeader("Cache-Control", "no-cache");
                    obj.Response.ContentType = "text/plain";
                    return;
                }
                string rangevalue = null;
                if (obj.Request.Headers.AllKeys.Contains("Range"))
                    rangevalue = obj.Request.Headers["Range"].Replace("bytes=", string.Empty).Trim();
                if (obj.Request.Headers.AllKeys.Contains("range"))
                    rangevalue = obj.Request.Headers["range"].Replace("bytes=", string.Empty).Trim();

                if (obj.Request.HttpMethod != "HEAD")
                {
                    FileSystemResult<Stream> fr = file.OpenRead();
                    if (fr == null || !fr.IsOk)
                    {
                        obj.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
                        obj.Response.StatusDescription = "Unable to open '" + fullname + "' " + fr?.Error ??
                                                         string.Empty;
                        return;
                    }
                    org = fr.Result;
                    long totalsize = org.Length;
                    long start = 0;
                    long end = 0;
                    if (!string.IsNullOrEmpty(rangevalue))
                    {
                        range = true;
                        string[] split = rangevalue.Split('-');
                        if (split.Length == 2)
                        {
                            if (string.IsNullOrEmpty(split[0]) && !string.IsNullOrEmpty(split[1]))
                            {
                                long e = long.Parse(split[1]);
                                start = totalsize - e;
                                end = totalsize - 1;
                            }
                            else if (!string.IsNullOrEmpty(split[0]) && string.IsNullOrEmpty(split[1]))
                            {
                                start = long.Parse(split[0]);
                                end = totalsize - 1;
                            }
                            else if (!string.IsNullOrEmpty(split[0]) && !string.IsNullOrEmpty(split[1]))
                            {
                                start = long.Parse(split[0]);
                                end = long.Parse(split[1]);
                                if (start > totalsize - 1)
                                    start = totalsize - 1;
                                if (end > totalsize - 1)
                                    end = totalsize - 1;
                            }
                            else
                            {
                                start = 0;
                                end = totalsize - 1;
                            }
                        }
                    }
                    SubStream outstream;
                    if (range)
                    {
                        obj.Response.StatusCode = (int) HttpStatusCode.PartialContent;
                        obj.Response.AddHeader("Content-Range", "bytes " + start + "-" + end + "/" + totalsize);
                        outstream = new SubStream(org, start, end - start + 1);
                        obj.Response.ContentLength64 = end - start + 1;
                    }
                    else
                    {
                        outstream = new SubStream(org, 0, totalsize);
                        obj.Response.ContentLength64 = totalsize;
                        obj.Response.StatusCode = (int) HttpStatusCode.OK;
                    }
                    if ((userid != 0) && (loc != null) && autowatch == 1)
                    {
                        outstream.CrossPosition = (long) ((double) totalsize*WatchedThreshold);
                        outstream.CrossPositionCrossed +=
                            (a) =>
                            {
                                Task.Factory.StartNew(() => { loc.ToggleWatchedStatus(true, userid); },
                                    new CancellationToken(),
                                    TaskCreationOptions.LongRunning, TaskScheduler.Default);
                            };
                    }
                    obj.Response.SendChunked = false;
                    outstream.CopyTo(obj.Response.OutputStream);
                    obj.Response.OutputStream.Close();
                    outstream.Close();
                }
                else
                {
                    obj.Response.SendChunked = false;
                    obj.Response.StatusCode = (int) HttpStatusCode.OK;
                    obj.Response.ContentLength64 = new FileInfo(fullname).Length;
                    obj.Response.KeepAlive = false;
                    obj.Response.OutputStream.Close();
                }
            }
            catch (HttpListenerException)
            {
                //ignored
            }
            catch (Exception e)
            {
                try
                {
                    obj.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    obj.Response.StatusDescription = "Internal Server Error";
                }
                catch
                {
                    // ignored
                }
                logger.Warn(e.ToString);
            }
            finally
            {
                try
                {
                    org?.Dispose();
                }
                catch
                {
                    // ignored
                }
                try
                {
                    obj?.Response.OutputStream?.Close();
                    obj?.Response.Close();
                }
                catch
                {
                    // ignored
                }
            }
        }
        internal override List<BuilderExtent> FixExtents(out long totalLength)
        {
            List<BuilderExtent> extents = new List<BuilderExtent>();

            MemoryStream descriptorStream = new MemoryStream();
            _descriptor.Write(descriptorStream);

            // Figure out grain size and number of grain tables, and adjust actual extent size to be a multiple
            // of grain size
            const int GtesPerGt = 512;
            long grainSize = 128;
            int numGrainTables = (int)Utilities.Ceil(_content.Length, grainSize * GtesPerGt * Sizes.Sector);

            long descriptorLength = 10 * Sizes.OneKiB; // Utilities.RoundUp(descriptorStream.Length, Sizes.Sector);
            long descriptorStart = 0;
            if (descriptorLength != 0)
            {
                descriptorStart = 1;
            }

            long redundantGrainDirStart = Math.Max(descriptorStart, 1) + Utilities.Ceil(descriptorLength, Sizes.Sector);
            long redundantGrainDirLength = numGrainTables * 4;

            long redundantGrainTablesStart = redundantGrainDirStart + Utilities.Ceil(redundantGrainDirLength, Sizes.Sector);
            long redundantGrainTablesLength = numGrainTables * Utilities.RoundUp(GtesPerGt * 4, Sizes.Sector);

            long grainDirStart = redundantGrainTablesStart + Utilities.Ceil(redundantGrainTablesLength, Sizes.Sector);
            long grainDirLength = numGrainTables * 4;

            long grainTablesStart = grainDirStart + Utilities.Ceil(grainDirLength, Sizes.Sector);
            long grainTablesLength = numGrainTables * Utilities.RoundUp(GtesPerGt * 4, Sizes.Sector);

            long dataStart = Utilities.RoundUp(grainTablesStart + Utilities.Ceil(grainTablesLength, Sizes.Sector), grainSize);

            // Generate the header, and write it
            HostedSparseExtentHeader header = new HostedSparseExtentHeader();
            header.Flags = HostedSparseExtentFlags.ValidLineDetectionTest | HostedSparseExtentFlags.RedundantGrainTable;
            header.Capacity = Utilities.RoundUp(_content.Length, grainSize * Sizes.Sector) / Sizes.Sector;
            header.GrainSize = grainSize;
            header.DescriptorOffset = descriptorStart;
            header.DescriptorSize = descriptorLength / Sizes.Sector;
            header.NumGTEsPerGT = GtesPerGt;
            header.RgdOffset = redundantGrainDirStart;
            header.GdOffset = grainDirStart;
            header.Overhead = dataStart;

            extents.Add(new BuilderBytesExtent(0, header.GetBytes()));

            // The descriptor extent
            if (descriptorLength > 0)
            {
                extents.Add(new BuilderStreamExtent(descriptorStart * Sizes.Sector, descriptorStream));
            }

            // The grain directory extents
            extents.Add(new GrainDirectoryExtent(redundantGrainDirStart * Sizes.Sector, redundantGrainTablesStart, numGrainTables, GtesPerGt));
            extents.Add(new GrainDirectoryExtent(grainDirStart * Sizes.Sector, grainTablesStart, numGrainTables, GtesPerGt));

            // For each graintable span that's present...
            long dataSectorsUsed = 0;
            long gtSpan = GtesPerGt * grainSize * Sizes.Sector;
            foreach (var gtRange in StreamExtent.Blocks(_content.Extents, grainSize * GtesPerGt * Sizes.Sector))
            {
                for (long i = 0; i < gtRange.Count; ++i)
                {
                    int gt = (int)(gtRange.Offset + i);

                    SubStream gtStream = new SubStream(_content, gt * gtSpan, Math.Min(gtSpan, _content.Length - (gt * gtSpan)));

                    GrainTableDataExtent dataExtent = new GrainTableDataExtent((dataStart + dataSectorsUsed) * Sizes.Sector, gtStream, grainSize);
                    extents.Add(dataExtent);

                    extents.Add(new GrainTableExtent(GrainTablePosition(redundantGrainTablesStart, gt, GtesPerGt), gtStream, dataStart + dataSectorsUsed, GtesPerGt, grainSize));
                    extents.Add(new GrainTableExtent(GrainTablePosition(grainTablesStart, gt, GtesPerGt), gtStream, dataStart + dataSectorsUsed, GtesPerGt, grainSize));

                    dataSectorsUsed += dataExtent.Length / Sizes.Sector;
                }
            }

            totalLength = (dataStart + dataSectorsUsed) * Sizes.Sector;
            return extents;
        }
Ejemplo n.º 10
0
        private void Import(Stream Source)
        {

            // Format from http://simswiki.info/wiki.php?title=Sims_3:0x6B20C4F3
            // Read Main Header


            //Stream F = File.Create(@"C:\temp\clips\test.clip");
            //Source.CopyTo(F);
            //F.Close();

            //Source.Position = 0;


            BinaryReader Reader = new BinaryReader(Source);

            UInt32 TID = Reader.ReadUInt32();
            if (TID != 0x6b20c4f3)
                throw new InvalidDataException();

            UInt32 Offset = Reader.ReadUInt32();
            UInt32 ClipSize = Reader.ReadUInt32();
            UInt32 ClipOffset = (UInt32)Reader.BaseStream.Position + Reader.ReadUInt32();
            UInt32 SlotOffset = (UInt32)Reader.BaseStream.Position + Reader.ReadUInt32();
            UInt32 ActorOffset = (UInt32)Reader.BaseStream.Position + Reader.ReadUInt32();
            UInt32 EventOffset = (UInt32)Reader.BaseStream.Position + Reader.ReadUInt32();

            Unknown1 = Reader.ReadUInt32();
            Unknown2 = Reader.ReadUInt32();

            UInt32 EndOffset = Reader.ReadUInt32();
            byte[] Buffer = Reader.ReadBytes(16);

            // get the end buffer values
            Reader.BaseStream.Position = EndOffset;
            EndData = new Single[4];
            EndData[0] = Reader.ReadSingle();
            EndData[1] = Reader.ReadSingle();
            EndData[2] = Reader.ReadSingle();
            EndData[3] = Reader.ReadSingle();

            // Get Clip
            Stream ClipStream = new SubStream(Source, ClipOffset, ClipSize);
            ImportClip(ClipStream);

            // Get Slot Table
            Stream SlotStream = new SubStream(Source, SlotOffset, ActorOffset - SlotOffset);
            ImportSlotTable(SlotStream);


            // Get Actor Name            
            Reader.BaseStream.Position = ActorOffset;
            

            int actorlen = (int)(EventOffset - ActorOffset);
            ActorName = ReadNullASCIIString(Reader, actorlen);

            // Get Event Table       
            Reader.BaseStream.Position = EventOffset;
            string ceSIG = Encoding.ASCII.GetString(Reader.ReadBytes(4));
            if (ceSIG != "=CE=")
                throw new InvalidDataException();

            UInt32 ceVersion = Reader.ReadUInt32();
            if (ceVersion != 0x0103)
                throw new InvalidDataException();

            UInt32 ceCount = Reader.ReadUInt32();
            UInt32 ceSize = Reader.ReadUInt32();
            UInt32 ceOffset = Reader.ReadUInt32();


            ClipTable = new ClipEvent[ceCount];

            for (int ceI = 0; ceI < ceCount; ceI++)
            {
                UInt16 ceType = Reader.ReadUInt16();

                ClipEvent Event;

                switch (ceType)
                {
                    case 1: Event = new ClipEventAttach(); break;
                    case 2: Event = new ClipEventUnParent(); break;
                    case 3: Event = new ClipEventPlaySound(); break;
                    case 4: Event = new ClipEventSACS(); break;
                    case 5: Event = new ClipEventPlayEffect(); break;
                    case 6: Event = new ClipEventVisibility(); break;
                    case 9: Event = new ClipEventDestroyProp(); break;
                    case 10: Event = new ClipEventStopEffect(); break;
                    default: throw new InvalidDataException();
                }

                ClipTable[ceI] = Event;

                Event.Import(Reader);               
                //Console.WriteLine(Event.ToString());                
            }


            Source.Close();
        }
Ejemplo n.º 11
0
        internal SparseStream OpenResourceStream(ShortResourceHeader hdr)
        {
            SparseStream fileSectionStream = new SubStream(_fileStream, Ownership.None, hdr.FileOffset, hdr.CompressedSize);
            if ((hdr.Flags & ResourceFlags.Compressed) == 0)
            {
                return fileSectionStream;
            }

            return new FileResourceStream(fileSectionStream, hdr, (_fileHeader.Flags & FileFlags.LzxCompression) != 0, _fileHeader.CompressionSize);
        }
Ejemplo n.º 12
0
        private static void InitializeDynamicInternal(Stream stream, long capacity, long blockSize)
        {
            if (blockSize < Sizes.OneMiB || blockSize > Sizes.OneMiB * 256 || !Utilities.IsPowerOfTwo(blockSize))
            {
                throw new ArgumentOutOfRangeException("blockSize", blockSize, "BlockSize must be a power of 2 between 1MB and 256MB");
            }

            int logicalSectorSize = 512;
            int physicalSectorSize = 4096;
            long chunkRatio = (0x800000L * logicalSectorSize) / blockSize;
            long dataBlocksCount = Utilities.Ceil(capacity, blockSize);
            long sectorBitmapBlocksCount = Utilities.Ceil(dataBlocksCount, chunkRatio);
            long totalBatEntriesDynamic = dataBlocksCount + ((dataBlocksCount - 1) / chunkRatio);

            FileHeader fileHeader = new FileHeader() { Creator = ".NET DiscUtils" };

            long fileEnd = Sizes.OneMiB;

            VhdxHeader header1 = new VhdxHeader();
            header1.SequenceNumber = 0;
            header1.FileWriteGuid = Guid.NewGuid();
            header1.DataWriteGuid = Guid.NewGuid();
            header1.LogGuid = Guid.Empty;
            header1.LogVersion = 0;
            header1.Version = 1;
            header1.LogLength = (uint)Sizes.OneMiB;
            header1.LogOffset = (ulong)fileEnd;
            header1.CalcChecksum();

            fileEnd += header1.LogLength;

            VhdxHeader header2 = new VhdxHeader(header1);
            header2.SequenceNumber = 1;
            header2.CalcChecksum();

            RegionTable regionTable = new RegionTable();

            RegionEntry metadataRegion = new RegionEntry();
            metadataRegion.Guid = RegionEntry.MetadataRegionGuid;
            metadataRegion.FileOffset = fileEnd;
            metadataRegion.Length = (uint)Sizes.OneMiB;
            metadataRegion.Flags = RegionFlags.Required;
            regionTable.Regions.Add(metadataRegion.Guid, metadataRegion);

            fileEnd += metadataRegion.Length;

            RegionEntry batRegion = new RegionEntry();
            batRegion.Guid = RegionEntry.BatGuid;
            batRegion.FileOffset = 3 * Sizes.OneMiB;
            batRegion.Length = (uint)Utilities.RoundUp(totalBatEntriesDynamic * 8, Sizes.OneMiB);
            batRegion.Flags = RegionFlags.Required;
            regionTable.Regions.Add(batRegion.Guid, batRegion);

            fileEnd += batRegion.Length;

            stream.Position = 0;
            Utilities.WriteStruct(stream, fileHeader);

            stream.Position = 64 * Sizes.OneKiB;
            Utilities.WriteStruct(stream, header1);

            stream.Position = 128 * Sizes.OneKiB;
            Utilities.WriteStruct(stream, header2);

            stream.Position = 192 * Sizes.OneKiB;
            Utilities.WriteStruct(stream, regionTable);

            stream.Position = 256 * Sizes.OneKiB;
            Utilities.WriteStruct(stream, regionTable);

            // Set stream to min size
            stream.Position = fileEnd - 1;
            stream.WriteByte(0);

            // Metadata
            FileParameters fileParams = new FileParameters() { BlockSize = (uint)blockSize, Flags = FileParametersFlags.None };
            ParentLocator parentLocator = new ParentLocator();

            Stream metadataStream = new SubStream(stream, metadataRegion.FileOffset, metadataRegion.Length);
            Metadata metadata = Metadata.Initialize(metadataStream, fileParams, (ulong)capacity, (uint)logicalSectorSize, (uint)physicalSectorSize, null);
        }
Ejemplo n.º 13
0
            internal override List<BuilderExtent> FixExtents(out long totalLength)
            {
                if (_diskType != DiskType.Dynamic)
                {
                    throw new NotSupportedException("Creation of only dynamic disks currently implemented");
                }

                List<BuilderExtent> extents = new List<BuilderExtent>();

                int logicalSectorSize = 512;
                int physicalSectorSize = 4096;
                long chunkRatio = (0x800000L * logicalSectorSize) / _blockSize;
                long dataBlocksCount = Utilities.Ceil(_content.Length, _blockSize);
                long sectorBitmapBlocksCount = Utilities.Ceil(dataBlocksCount, chunkRatio);
                long totalBatEntriesDynamic = dataBlocksCount + ((dataBlocksCount - 1) / chunkRatio);

                FileHeader fileHeader = new FileHeader() { Creator = ".NET DiscUtils" };

                long fileEnd = Sizes.OneMiB;

                VhdxHeader header1 = new VhdxHeader();
                header1.SequenceNumber = 0;
                header1.FileWriteGuid = Guid.NewGuid();
                header1.DataWriteGuid = Guid.NewGuid();
                header1.LogGuid = Guid.Empty;
                header1.LogVersion = 0;
                header1.Version = 1;
                header1.LogLength = (uint)Sizes.OneMiB;
                header1.LogOffset = (ulong)fileEnd;
                header1.CalcChecksum();

                fileEnd += header1.LogLength;

                VhdxHeader header2 = new VhdxHeader(header1);
                header2.SequenceNumber = 1;
                header2.CalcChecksum();

                RegionTable regionTable = new RegionTable();

                RegionEntry metadataRegion = new RegionEntry();
                metadataRegion.Guid = RegionEntry.MetadataRegionGuid;
                metadataRegion.FileOffset = fileEnd;
                metadataRegion.Length = (uint)Sizes.OneMiB;
                metadataRegion.Flags = RegionFlags.Required;
                regionTable.Regions.Add(metadataRegion.Guid, metadataRegion);

                fileEnd += metadataRegion.Length;

                RegionEntry batRegion = new RegionEntry();
                batRegion.Guid = RegionEntry.BatGuid;
                batRegion.FileOffset = fileEnd;
                batRegion.Length = (uint)Utilities.RoundUp(totalBatEntriesDynamic * 8, Sizes.OneMiB);
                batRegion.Flags = RegionFlags.Required;
                regionTable.Regions.Add(batRegion.Guid, batRegion);

                fileEnd += batRegion.Length;

                extents.Add(ExtentForStruct(fileHeader, 0));
                extents.Add(ExtentForStruct(header1, 64 * Sizes.OneKiB));
                extents.Add(ExtentForStruct(header2, 128 * Sizes.OneKiB));
                extents.Add(ExtentForStruct(regionTable, 192 * Sizes.OneKiB));
                extents.Add(ExtentForStruct(regionTable, 256 * Sizes.OneKiB));

                // Metadata
                FileParameters fileParams = new FileParameters() { BlockSize = (uint)_blockSize, Flags = FileParametersFlags.None };
                ParentLocator parentLocator = new ParentLocator();

                byte[] metadataBuffer = new byte[metadataRegion.Length];
                MemoryStream metadataStream = new MemoryStream(metadataBuffer);
                Metadata.Initialize(metadataStream, fileParams, (ulong)_content.Length, (uint)logicalSectorSize, (uint)physicalSectorSize, null);
                extents.Add(new BuilderBufferExtent(metadataRegion.FileOffset, metadataBuffer));

                List<Range<long, long>> presentBlocks = new List<Range<long, long>>(StreamExtent.Blocks(_content.Extents, _blockSize));

                // BAT
                BlockAllocationTableBuilderExtent batExtent = new BlockAllocationTableBuilderExtent(batRegion.FileOffset, batRegion.Length, presentBlocks, fileEnd, _blockSize, chunkRatio);
                extents.Add(batExtent);

                // Stream contents
                foreach (var range in presentBlocks)
                {
                    long substreamStart = range.Offset * _blockSize;
                    long substreamCount = Math.Min(_content.Length - substreamStart, range.Count * _blockSize);

                    SubStream dataSubStream = new SubStream(_content, substreamStart, substreamCount);
                    BuilderSparseStreamExtent dataExtent = new BuilderSparseStreamExtent(fileEnd, dataSubStream);
                    extents.Add(dataExtent);

                    fileEnd += range.Count * _blockSize;
                }

                totalLength = fileEnd;

                return extents;
            }
Ejemplo n.º 14
0
        public Stream OpenFile(string path)
        {
            var entry = GetEntry(path);
            if (entry == null) throw new FileNotFoundException();

            lock (this)
            {
                if (!_streams.ContainsKey(entry.ArchiveIndex))
                {
                    var file = _directory.Chunks[entry.ArchiveIndex];
                    var stream = _directory.OpenFile(file);
                    _streams.Add(entry.ArchiveIndex, stream);
                }
            }

            var offset = entry.ArchiveIndex == VpkDirectory.DirectoryIndex ? _directory.HeaderLength + _directory.TreeLength + entry.EntryOffset : entry.EntryOffset;
            var sub = new SubStream(_streams[entry.ArchiveIndex], offset, entry.EntryLength);
            return new BufferedStream(new VpkEntryStream(entry, sub));
        }
Ejemplo n.º 15
0
        public override void Write(byte[] buffer, int offset, int count)
        {
            SubStream str = Substreams.SingleOrDefault(s => s.StartPosition <= Position && s.StartPosition + s.Length >= Position);
            if (str == null)
            {
                str = new SubStream(Position);
                Substreams.Add(str);
            }

            List<SubStream> overlappedStreams = Substreams.Where(s => s != str && s.StartPosition >= Position && s.StartPosition < Position + count).ToList();
            foreach (SubStream s in overlappedStreams)
            {
                str.Seek(s.StartPosition - str.StartPosition, SeekOrigin.Begin);
                s.Seek(0, SeekOrigin.Begin);
                s.CopyTo(str);
                Substreams.Remove(s);
            }

            str.Seek(Position - str.StartPosition, SeekOrigin.Begin);
            str.Write(buffer, offset, count);

            Position = str.StartPosition + str.Position;
        }