ntdll: Implement semi-stub for LZNT1 compression in RtlCompressBuffer.

This stub implementation just emits uncompressed blocks with
appropriate chunk headers.
This commit is contained in:
Sebastian Lackner 2015-07-09 03:05:27 +02:00 committed by Alexandre Julliard
parent 025ea11dc4
commit 275424e939
2 changed files with 50 additions and 14 deletions

View File

@ -1234,19 +1234,61 @@ NTSTATUS WINAPI RtlGetCompressionWorkSpaceSize(USHORT CompressionFormatAndEngine
return STATUS_NOT_IMPLEMENTED;
}
/* compress data using LZNT1, currently only a stub */
static NTSTATUS lznt1_compress(UCHAR *src, ULONG src_size, UCHAR *dst, ULONG dst_size,
ULONG chunk_size, ULONG *final_size, UCHAR *workspace)
{
UCHAR *src_cur = src, *src_end = src + src_size;
UCHAR *dst_cur = dst, *dst_end = dst + dst_size;
ULONG block_size;
while (src_cur < src_end)
{
/* determine size of current chunk */
block_size = min(0x1000, src_end - src_cur);
if (dst_cur + sizeof(WORD) + block_size > dst_end)
return STATUS_BUFFER_TOO_SMALL;
/* write (uncompressed) chunk header */
*(WORD *)dst_cur = 0x3000 | (block_size - 1);
dst_cur += sizeof(WORD);
/* write chunk content */
memcpy(dst_cur, src_cur, block_size);
dst_cur += block_size;
src_cur += block_size;
}
if (final_size)
*final_size = dst_cur - dst;
return STATUS_SUCCESS;
}
/******************************************************************************
* RtlCompressBuffer [NTDLL.@]
*/
NTSTATUS WINAPI RtlCompressBuffer(USHORT CompressionFormatAndEngine, PUCHAR UncompressedBuffer,
ULONG UncompressedBufferSize, PUCHAR CompressedBuffer,
ULONG CompressedBufferSize, ULONG UncompressedChunkSize,
PULONG FinalCompressedSize, PVOID WorkSpace)
NTSTATUS WINAPI RtlCompressBuffer(USHORT format, PUCHAR uncompressed, ULONG uncompressed_size,
PUCHAR compressed, ULONG compressed_size, ULONG chunk_size,
PULONG final_size, PVOID workspace)
{
FIXME("0x%04x, %p, %u, %p, %u, %u, %p, %p :stub\n", CompressionFormatAndEngine, UncompressedBuffer,
UncompressedBufferSize, CompressedBuffer, CompressedBufferSize, UncompressedChunkSize,
FinalCompressedSize, WorkSpace);
FIXME("0x%04x, %p, %u, %p, %u, %u, %p, %p: semi-stub\n", format, uncompressed,
uncompressed_size, compressed, compressed_size, chunk_size, final_size, workspace);
return STATUS_NOT_IMPLEMENTED;
switch (format & ~COMPRESSION_ENGINE_MAXIMUM)
{
case COMPRESSION_FORMAT_LZNT1:
return lznt1_compress(uncompressed, uncompressed_size, compressed,
compressed_size, chunk_size, final_size, workspace);
case COMPRESSION_FORMAT_NONE:
case COMPRESSION_FORMAT_DEFAULT:
return STATUS_INVALID_PARAMETER;
default:
FIXME("format %u not implemented\n", format);
return STATUS_UNSUPPORTED_COMPRESSION;
}
}
/******************************************************************************

View File

@ -1636,21 +1636,18 @@ static void test_RtlCompressBuffer(void)
final_size = 0xdeadbeef;
status = pRtlCompressBuffer(COMPRESSION_FORMAT_NONE, test_buffer, sizeof(test_buffer),
buf1, sizeof(buf1) - 1, 4096, &final_size, workspace);
todo_wine
ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08x\n", status);
ok(final_size == 0xdeadbeef, "got wrong final_size %u\n", final_size);
final_size = 0xdeadbeef;
status = pRtlCompressBuffer(COMPRESSION_FORMAT_DEFAULT, test_buffer, sizeof(test_buffer),
buf1, sizeof(buf1) - 1, 4096, &final_size, workspace);
todo_wine
ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08x\n", status);
ok(final_size == 0xdeadbeef, "got wrong final_size %u\n", final_size);
final_size = 0xdeadbeef;
status = pRtlCompressBuffer(0xFF, test_buffer, sizeof(test_buffer),
buf1, sizeof(buf1) - 1, 4096, &final_size, workspace);
todo_wine
ok(status == STATUS_UNSUPPORTED_COMPRESSION, "got wrong status 0x%08x\n", status);
ok(final_size == 0xdeadbeef, "got wrong final_size %u\n", final_size);
@ -1659,9 +1656,7 @@ static void test_RtlCompressBuffer(void)
memset(buf1, 0x11, sizeof(buf1));
status = pRtlCompressBuffer(COMPRESSION_FORMAT_LZNT1, test_buffer, sizeof(test_buffer),
buf1, sizeof(buf1), 4096, &final_size, workspace);
todo_wine
ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status);
todo_wine
ok((*(WORD *)buf1 & 0x7000) == 0x3000, "no chunk signature found %04x\n", *(WORD *)buf1);
todo_wine
ok(final_size < sizeof(test_buffer), "got wrong final_size %u\n", final_size);
@ -1685,7 +1680,6 @@ static void test_RtlCompressBuffer(void)
memset(buf1, 0x11, sizeof(buf1));
status = pRtlCompressBuffer(COMPRESSION_FORMAT_LZNT1, test_buffer, sizeof(test_buffer),
buf1, 4, 4096, &final_size, workspace);
todo_wine
ok(status == STATUS_BUFFER_TOO_SMALL, "got wrong status 0x%08x\n", status);
HeapFree(GetProcessHeap(), 0, workspace);