예제 #1
0
        /// <summary>
        /// Reads the streams from the file.
        /// </summary>
        private void InitStreams()
        {
            //Open the file with backup semantics
            IntPtr hFile = Kernel32.CreateFile(_file.FullName, Kernel32.FileAccessAPI.GENERIC_READ, FileShare.Read, IntPtr.Zero, FileMode.Open, Kernel32.FileFlags.BackupSemantics, IntPtr.Zero);

            if (hFile.ToInt32() == Kernel32.INVALID_HANDLE_VALUE)
            {
                return;
            }

            try
            {
                Kernel32.WIN32_STREAM_ID sid = new Kernel32.WIN32_STREAM_ID();
                uint   dwStreamHeaderSize    = (uint)Marshal.SizeOf(sid);
                IntPtr context   = IntPtr.Zero;
                bool   @continue = true;
                while (@continue)
                {
                    //Read the next stream header
                    uint lRead = 0;
                    @continue = Kernel32.BackupRead(hFile, ref sid, dwStreamHeaderSize, out lRead, false, false, ref context);
                    if (@continue && lRead == dwStreamHeaderSize)
                    {
                        if (sid.dwStreamNameSize > 0)
                        {
                            //Read the stream name
                            lRead = 0;
                            IntPtr pName = Marshal.AllocHGlobal(sid.dwStreamNameSize);
                            try
                            {
                                @continue = Kernel32.BackupRead(hFile, pName, (uint)sid.dwStreamNameSize, out lRead, false, false, ref context);
                                char[] bName = new char[sid.dwStreamNameSize];
                                Marshal.Copy(pName, bName, 0, sid.dwStreamNameSize);

                                //Name is of the format ":NAME:$DATA\0"
                                string sName = new string(bName);
                                int    i     = sName.IndexOf(Kernel32.STREAM_SEP, 1);
                                if (i > -1)
                                {
                                    sName = sName.Substring(1, i - 1);
                                }
                                else
                                {
                                    //This should never happen.
                                    //Truncate the name at the first null char.
                                    i = sName.IndexOf('\0');
                                    if (i > -1)
                                    {
                                        sName = sName.Substring(1, i - 1);
                                    }
                                }

                                //Add the stream to the collection
                                base.List.Add(new StreamInfo(this, sName, sid.Size.ToInt64()));
                            }
                            finally
                            {
                                Marshal.FreeHGlobal(pName);
                            }
                        }

                        //Skip the stream contents
                        uint l; uint h;
                        @continue = Kernel32.BackupSeek(hFile, (uint)sid.Size.Low, (uint)sid.Size.High, out l, out h, ref context);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            finally
            {
                Kernel32.CloseHandle(hFile);
            }
        }
예제 #2
0
        /// <summary>
        /// Reads the streams from the file.
        /// </summary>
        private void InitStreams()
        {
            //Open the file with backup semantics
            IntPtr hFile = Kernel32.CreateFile(_file.FullName, Kernel32.FileAccessAPI.GENERIC_READ, FileShare.Read, IntPtr.Zero, FileMode.Open, Kernel32.FileFlags.BackupSemantics, IntPtr.Zero);
            if (hFile.ToInt32() == Kernel32.INVALID_HANDLE_VALUE) return;

            try
            {
                Kernel32.WIN32_STREAM_ID sid = new Kernel32.WIN32_STREAM_ID();
                uint dwStreamHeaderSize = (uint)Marshal.SizeOf(sid);
                IntPtr context = IntPtr.Zero;
                bool @continue = true;
                while (@continue)
                {
                    //Read the next stream header
                    uint lRead = 0;
                    @continue = Kernel32.BackupRead(hFile, ref sid, dwStreamHeaderSize, out lRead, false, false, ref context);
                    if (@continue && lRead == dwStreamHeaderSize)
                    {
                        if (sid.dwStreamNameSize > 0)
                        {
                            //Read the stream name
                            lRead = 0;
                            IntPtr pName = Marshal.AllocHGlobal(sid.dwStreamNameSize);
                            try
                            {
                                @continue = Kernel32.BackupRead(hFile, pName, (uint)sid.dwStreamNameSize, out lRead, false, false, ref context);
                                char[] bName = new char[sid.dwStreamNameSize];
                                Marshal.Copy(pName, bName, 0, sid.dwStreamNameSize);

                                //Name is of the format ":NAME:$DATA\0"
                                string sName = new string(bName);
                                int i = sName.IndexOf(Kernel32.STREAM_SEP, 1);
                                if (i > -1) sName = sName.Substring(1, i - 1);
                                else
                                {
                                    //This should never happen. 
                                    //Truncate the name at the first null char.
                                    i = sName.IndexOf('\0');
                                    if (i > -1) sName = sName.Substring(1, i - 1);
                                }

                                //Add the stream to the collection
                                base.List.Add(new StreamInfo(this, sName, sid.Size.ToInt64()));
                            }
                            finally
                            {
                                Marshal.FreeHGlobal(pName);
                            }
                        }

                        //Skip the stream contents
                        uint l; uint h;
                        @continue = Kernel32.BackupSeek(hFile, (uint)sid.Size.Low, (uint)sid.Size.High, out l, out h, ref context);
                    }
                    else break;
                }
            }
            finally
            {
                Kernel32.CloseHandle(hFile);
            }
        }