ntdll/NtSetEaFile.ps1
function NtSetEaFile { <# .SYNOPSIS The NtSetEaFile routine sets extended-attribute (EA) values for a file. .DESCRIPTION .NOTES Author: Jared Atkinson (@jaredcatkinson) License: BSD 3-Clause Required Dependencies: PSReflect, IO_STATUS_BLOCK (Structure), FILE_FULL_EA_INFORMATION (Structure) Optional Dependencies: None (func ntdll NtSetEaFile ([UInt32]) @( [IntPtr], #_In_ HANDLE FileHandle $IO_STATUS_BLOCK.MakeByRefType(), #_Out_ PIO_STATUS_BLOCK IoStatusBlock [IntPtr], #_In_ PVOID Buffer [UInt32] #_In_ ULONG Length ) -EntryPoint NtSetEaFile) .LINK https://msdn.microsoft.com/en-us/library/windows/hardware/ff961908(v=vs.85).aspx .EXAMPLE #> param ( [Parameter(Mandatory = $true)] [IntPtr] $FileHandle, [Parameter(Mandatory = $true)] [string] $Name, [Parameter(Mandatory = $true)] [byte[]] $Value ) # Instantiate an IO_STATUS_BLOCK instance $IoStatusBlock = [Activator]::CreateInstance($IO_STATUS_BLOCK) # Instatiate a FILE_FULL_EA_INFORMATION instance $FileFullEaInformation = [Activator]::CreateInstance($FILE_FULL_EA_INFORMATION) $FileFullEaInformation.NextEntryOffset = 0 $FileFullEaInformation.Flags = 0 $FileFullEaInformation.EaNameLength = $Name.Length $FileFullEaInformation.EaValueLength = $Value.Length # Initialize a buffer for the FILE_FULL_EA_INFORMATION struct $Size = 8 + $Name.Length + 1 + $Value.Length $buffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($Size) [System.Runtime.InteropServices.Marshal]::StructureToPtr($FileFullEaInformation, $buffer, $true) $NameBytes = [System.Text.Encoding]::ASCII.GetBytes($Name) $NameOffset = [IntPtr]::Add($buffer, 8) [System.Runtime.InteropServices.Marshal]::Copy($NameBytes, 0, $NameOffset, $Name.Length) $ValueOffset = [IntPtr]::Add($buffer, 8 + $Name.Length + 1) [System.Runtime.InteropServices.Marshal]::Copy($Value, 0, $ValueOffset, $Value.Length) $SUCCESS = $Ntdll::NtSetEaFile($FileHandle, [ref]$IoStatusBlock, $buffer, $Size); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error() [System.Runtime.InteropServices.Marshal]::FreeHGlobal($buffer) if($SUCCESS -ne 0) # NT_SUCCESS { throw "[NtSetEaFile] Error: $(([ComponentModel.Win32Exception] $LastError).Message)" } } |