コード例 #1
0
		public override IEnumerable<ContentInfo> GetContentInfos(string path)
		{
			long length;
			var contentInfos = new List<ContentInfo>();

			try
			{
				length = new FileInfo(path).Length;
			}
			catch (FileNotFoundException)
			{
				yield break;
			}

			yield return new ContentInfo(this.DefaultContentName, length);

			var hFile = Kernel32.CreateFileW(path, (int)FileAccess.Read, (int)FileShare.ReadWrite, IntPtr.Zero, (int)FileMode.Open, (int)Kernel32.FileFlags.BackupSemantics, IntPtr.Zero);

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

			try
			{
				var sid = new Kernel32.WIN32_STREAM_ID();
				var dwStreamHeaderSize = Marshal.SizeOf(sid);
				var context = new IntPtr();
				var shouldContinue = true;

				while (shouldContinue)
				{
					var lRead = 0;

					shouldContinue = Kernel32.BackupRead(hFile, ref sid, dwStreamHeaderSize, ref lRead, false, false, ref context);

					if (shouldContinue && lRead == dwStreamHeaderSize)
					{
						if (sid.dwStreamNameSize > 0)
						{
							var pName = Marshal.AllocHGlobal(sid.dwStreamNameSize);
							
							lRead = 0;

							try
							{
								shouldContinue = Kernel32.BackupRead(hFile, pName, sid.dwStreamNameSize, ref lRead, false, false, ref context);

								var bName = new char[sid.dwStreamNameSize];

								Marshal.Copy(pName, bName, 0, sid.dwStreamNameSize);

								// Name Format ":NAME:$DATA\0"

								var streamName = new string(bName);
								var i = streamName.IndexOf(Kernel32.STREAM_SEPERATOR, 1, StringComparison.Ordinal);

								if (i > -1)
								{
									streamName = streamName.Substring(1, i - 1);
								}
								else
								{
									i = streamName.IndexOf('\0');

									if (i > -1)
									{
										streamName = streamName.Substring(1, i - 1);
									}
								}

								contentInfos.Add(new ContentInfo(streamName, sid.Size.ToInt64()));
							}
							finally
							{
								Marshal.FreeHGlobal(pName);
							}
						}

						// Skip the stream contents

						var l = 0;
						var h = 0;

						shouldContinue = Kernel32.BackupSeek(hFile, sid.Size.Low, sid.Size.High, ref l, ref h, ref context);
					}
					else
					{
						break;
					}
				}
			}
			finally
			{
				Kernel32.CloseHandle(hFile);
			}

			foreach (var contentInfo in contentInfos)
			{
				yield return contentInfo;
			}
		}
コード例 #2
0
        public override IEnumerable <ContentInfo> GetContentInfos(string path)
        {
            long length;
            var  contentInfos = new List <ContentInfo>();

            try
            {
                length = new FileInfo(path).Length;
            }
            catch (FileNotFoundException)
            {
                yield break;
            }

            yield return(new ContentInfo(this.DefaultContentName, length));

            var hFile = Kernel32.CreateFileW(path, (int)FileAccess.Read, (int)FileShare.ReadWrite, IntPtr.Zero, (int)FileMode.Open, (int)Kernel32.FileFlags.BackupSemantics, IntPtr.Zero);

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

            try
            {
                var sid = new Kernel32.WIN32_STREAM_ID();
                var dwStreamHeaderSize = Marshal.SizeOf(sid);
                var context            = new IntPtr();
                var shouldContinue     = true;

                while (shouldContinue)
                {
                    var lRead = 0;

                    shouldContinue = Kernel32.BackupRead(hFile, ref sid, dwStreamHeaderSize, ref lRead, false, false, ref context);

                    if (shouldContinue && lRead == dwStreamHeaderSize)
                    {
                        if (sid.dwStreamNameSize > 0)
                        {
                            var pName = Marshal.AllocHGlobal(sid.dwStreamNameSize);

                            lRead = 0;

                            try
                            {
                                shouldContinue = Kernel32.BackupRead(hFile, pName, sid.dwStreamNameSize, ref lRead, false, false, ref context);

                                var bName = new char[sid.dwStreamNameSize];

                                Marshal.Copy(pName, bName, 0, sid.dwStreamNameSize);

                                // Name Format ":NAME:$DATA\0"

                                var streamName = new string(bName);
                                var i          = streamName.IndexOf(Kernel32.STREAM_SEPERATOR, 1, StringComparison.Ordinal);

                                if (i > -1)
                                {
                                    streamName = streamName.Substring(1, i - 1);
                                }
                                else
                                {
                                    i = streamName.IndexOf('\0');

                                    if (i > -1)
                                    {
                                        streamName = streamName.Substring(1, i - 1);
                                    }
                                }

                                contentInfos.Add(new ContentInfo(streamName, sid.Size.ToInt64()));
                            }
                            finally
                            {
                                Marshal.FreeHGlobal(pName);
                            }
                        }

                        // Skip the stream contents

                        var l = 0;
                        var h = 0;

                        shouldContinue = Kernel32.BackupSeek(hFile, sid.Size.Low, sid.Size.High, ref l, ref h, ref context);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            finally
            {
                Kernel32.CloseHandle(hFile);
            }

            foreach (var contentInfo in contentInfos)
            {
                yield return(contentInfo);
            }
        }