.net - RtlCompressBuffer API in C# -
.net - RtlCompressBuffer API in C# -
i'm trying utilize rtlgetcompressionworkspacesize , rtlcompressbuffer functions in c# project.
here have far:
class programme { const uint compression_format_lznt1 = 2; const uint compression_engine_maximum = 0x100; [dllimport("ntdll.dll")] static extern uint rtlgetcompressionworkspacesize(uint compressionformat, out uint pneededbuffersize, out uint unknown); [dllimport("ntdll.dll")] static extern uint rtlcompressbuffer(uint compressionformat, byte[] sourcebuffer, uint sourcebufferlength, out byte[] destinationbuffer, uint destinationbufferlength, uint unknown, out uint pdestinationsize, intptr workspacebuffer); static void main(string[] args) { uint dwsize = 0; uint dwret = 0; uint ret = rtlgetcompressionworkspacesize(compression_format_lznt1 | compression_engine_maximum, out dwsize, out dwret); intptr pmem = marshal.allochglobal((int)dwsize); byte[] buffer = new byte[1024]; byte[] outbuf = new byte[1024]; uint destsize = 0; ret = rtlcompressbuffer(compression_format_lznt1 | compression_engine_maximum, buffer, 1024, out outbuf, 1024, 0, out destsize, pmem); console.write(ret.tostring()); console.read(); } } rtlgetcompressionworkspacesize works since returns 0 (nt success code) when phone call rtlcompressbuffer memory access violation error.
edit: help david's reply i've fixed issue , right code below.
const ushort compression_format_lznt1 = 2; const ushort compression_engine_maximum = 0x100; [dllimport("ntdll.dll")] static extern uint rtlgetcompressionworkspacesize(ushort compressionformat, out uint pneededbuffersize, out uint unknown); [dllimport("ntdll.dll")] static extern uint rtlcompressbuffer(ushort compressionformat, byte[] sourcebuffer, int sourcebufferlength, byte[] destinationbuffer, int destinationbufferlength, uint unknown, out int pdestinationsize, intptr workspacebuffer); [dllimport("kernel32.dll", charset = charset.auto, setlasterror = true)] internal static extern intptr localalloc(int uflags, intptr sizetdwbytes); [dllimport("kernel32.dll", setlasterror = true)] static extern intptr localfree(intptr hmem); internal static byte[] compress(byte[] buffer) { var outbuf = new byte[buffer.length * 6]; uint dwsize = 0, dwret = 0; uint ret = rtlgetcompressionworkspacesize(compression_format_lznt1 | compression_engine_maximum, out dwsize, out dwret); if (ret != 0) { homecoming null; } int dstsize = 0; intptr hwork = localalloc(0, new intptr(dwsize)); ret = rtlcompressbuffer(compression_format_lznt1 | compression_engine_maximum, buffer, buffer.length, outbuf, outbuf.length, 0, out dstsize, hwork); if (ret != 0) { homecoming null; } localfree(hwork); array.resize(ref outbuf, dstsize); homecoming outbuf; }
you there. problem part of p/invoke rtlcompressbuffer:
out byte[] destinationbuffer the default marshalling byte[] array contents marshalled in both directions, managed unmanaged, , 1 time again when function returns. c definition of rtlcompressbuffer annotated __out means array contents __out rather pointer beingness __out.
change p/invoke
byte[] destinationbuffer and in phone call rtlcompressbuffer alter out outbuf outbuf , should go.
be warned code stands homecoming status code of status_buffer_all_zeros don't tricked thinking non-zero homecoming value indicates failure.
one final point, first parameter both p/invokes, compressionformat, should declared ushort.
c# .net winapi pinvoke
Comments
Post a Comment