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:
parent
025ea11dc4
commit
275424e939
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user