[2/7] ntdll: Implement semi-stub for LZNT1 compression in RtlCompressBuffer. (v2)

Sebastian Lackner sebastian at fds-team.de
Wed Jul 8 20:05:27 CDT 2015


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);
-- 
2.4.5



More information about the wine-patches mailing list