//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
//  
using System;
using System.Threading;
using System.IO;
using System.Security;
using System.Security.Permissions;

namespace ProfilingSamples
{
	public class SecurityAttributesMain 
	{
		[FileIOPermissionAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
		public static void CopyFile(String srcPath, String dstPath) 
		{
			// W pozostałej części metody żądania odczytu pliku źródłowego i żądania
			// zapisu pliku docelowego będą przydzielane natychmiast. Sprawdzanie
			// dalszej części stosu nie jest wymagane.

			FileInfo srcFile = new FileInfo(srcPath);
			FileInfo dstFile = new FileInfo(dstPath);
			Stream src = srcFile.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
			Stream dst = dstFile.Open(FileMode.Create, FileAccess.Write, FileShare.None);
			if (srcFile.Length > Int32.MaxValue)
				throw new Exception("CopyFile wymaga, aby wielkość pliku źródłowego nie przekraczała 2 GB.");
			Byte[] buffer = new Byte[(Int32) srcFile.Length];
			src.Read(buffer, 0, (Int32) srcFile.Length);
			dst.Write(buffer, 0, (Int32) srcFile.Length);
			//dstFile.CreationTime   = srcFile.CreationTime;
			//dstFile.LastAccessTime = srcFile.LastAccessTime;
			//dstFile.LastWriteTime  = srcFile.LastWriteTime;
			src.Close();
			dst.Close();
		}
		void RecurseSecurityCheck(int i)
		{
			if(i > 0)
				RecurseSecurityCheck(i - 1);
			else
			{
				CopyFile(".\\Security.exe", ".\\Security.copy.exe");
			}
		}
		void TestThread()
		{
			try
			{
				while(true)
				{
					RecurseSecurityCheck(50);
					Thread.Sleep(100);
				}
			}
			catch(Exception e)
			{
				Console.WriteLine("TestThread przerywa pracę: ", e.Message);
			}
		}
		static void Main(string [] args)
		{
			SecurityAttributesMain m = new SecurityAttributesMain();
			Thread testThread = new Thread(new ThreadStart(m.TestThread));
			testThread.Start();
			string input = Console.ReadLine();
			testThread.Abort();
			testThread.Join();
		}
	}
}