Sebastian Lackner : ntdll: Implement semi-stub for LZNT1 compression in RtlCompressBuffer.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Jul 9 09:44:37 CDT 2015
Module: wine
Branch: master
Commit: 275424e939d850593d1dbd173d928e607411a6aa
URL: http://source.winehq.org/git/wine.git/?a=commit;h=275424e939d850593d1dbd173d928e607411a6aa
Author: Sebastian Lackner <sebastian at fds-team.de>
Date: Thu Jul 9 03:05:27 2015 +0200
ntdll: Implement semi-stub for LZNT1 compression in RtlCompressBuffer.
This stub implementation just emits uncompressed blocks with
appropriate chunk headers.
---
dlls/ntdll/rtl.c | 58 +++++++++++++++++++++++++++++++++++++++++++-------
dlls/ntdll/tests/rtl.c | 6 ------
2 files changed, 50 insertions(+), 14 deletions(-)
diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c
index 855bdb9..8bbb610 100644
--- a/dlls/ntdll/rtl.c
+++ b/dlls/ntdll/rtl.c
@@ -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;
+ }
}
/******************************************************************************
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
index 0b64d95..755424c 100644
--- a/dlls/ntdll/tests/rtl.c
+++ b/dlls/ntdll/tests/rtl.c
@@ -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);
More information about the wine-cvs
mailing list