param(
	[string]$basePath,
	[string]$ownersFile
)

# Windows does not allow to change file owner by default, even if you are Administrator.
# To change owner you have to raise your privileges in explicit way. Code is taken from:
# http://www.leeholmes.com/blog/2010/09/24/adjusting-token-privileges-in-powershell/
# and originally taken from P/Invoke.NET with minor adjustments.

$definition = @'

using System;
using System.Runtime.InteropServices;

public class AdjPriv
{
	[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]

	internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,

	ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
	[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]

	internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
	[DllImport("advapi32.dll", SetLastError = true)]

	internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
	[StructLayout(LayoutKind.Sequential, Pack = 1)]

	internal struct TokPriv1Luid
	{
		public int Count;
		public long Luid;
		public int Attr;
	}
	internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
	internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
	internal const int TOKEN_QUERY = 0x00000008;
	internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;

	public static bool EnablePrivilege(long processHandle, string privilege, bool disable)
	{
		bool retVal;
		TokPriv1Luid tp;
		IntPtr hproc = new IntPtr(processHandle);
		IntPtr htok = IntPtr.Zero;
		retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
		tp.Count = 1;
		tp.Luid = 0;
		if(disable) {
			tp.Attr = SE_PRIVILEGE_DISABLED;
		} else {
			tp.Attr = SE_PRIVILEGE_ENABLED;
		}
		retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
		retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
		return retVal;
	}
}
'@

Write-Host "Raise process priviledges so it can change file owners"
$processHandle = (Get-Process -id $pid).Handle
$type = Add-Type $definition -PassThru
$type[0]::EnablePrivilege($processHandle, 'SeRestorePrivilege', $false)

# Read XML and set owners accordingly

[xml]$xml = get-content $ownersFile

foreach ($fileNode in $xml.owners.file) {
	$filePath = $basePath + "\\" + $fileNode.path
	$fileOwner = $fileNode.owner
	Write-Host "Set owner of $filePath to $fileOwner"

	$acl = Get-Acl $filePath
	$user = New-Object System.Security.Principal.NTAccount($fileOwner)
	$acl.setOwner($user)
	Set-Acl -aclobject $acl -path $filePath
}

