diff --git a/debian/changelog b/debian/changelog index 7f89c32c..6e49ea0f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,8 @@ wine-staging (1.7.47) UNRELEASED; urgency=low * Removed patch to initialize *end with NULL on failure in msvcrt.strtod (accepted upstream). * Removed patchset for new Threadpool implementation (accepted upstream). + * Partially removed patches for RtlDecompressBuffer implementation (accepted + upstream). -- Sebastian Lackner Mon, 29 Jun 2015 19:39:04 +0200 wine-staging (1.7.46) unstable; urgency=low diff --git a/patches/ntdll-LZNT1_Compression/0003-ntdll-Implement-LZNT1-algorithm-for-RtlDecompressBuf.patch b/patches/ntdll-LZNT1_Compression/0001-ntdll-Implement-RtlDecompressFragment.patch similarity index 80% rename from patches/ntdll-LZNT1_Compression/0003-ntdll-Implement-LZNT1-algorithm-for-RtlDecompressBuf.patch rename to patches/ntdll-LZNT1_Compression/0001-ntdll-Implement-RtlDecompressFragment.patch index 23812348..ac8b5b51 100644 --- a/patches/ntdll-LZNT1_Compression/0003-ntdll-Implement-LZNT1-algorithm-for-RtlDecompressBuf.patch +++ b/patches/ntdll-LZNT1_Compression/0001-ntdll-Implement-RtlDecompressFragment.patch @@ -1,23 +1,26 @@ -From ac70c24f5e811828739b6e8c51d1b3e26c6a5d04 Mon Sep 17 00:00:00 2001 +From 0955227f8eddd188b2c953d82224fc7c9de34ecd Mon Sep 17 00:00:00 2001 From: Sebastian Lackner -Date: Thu, 30 Oct 2014 17:26:42 +0100 -Subject: ntdll: Implement LZNT1 algorithm for RtlDecompressBuffer. +Date: Thu, 9 Jul 2015 03:07:03 +0200 +Subject: ntdll: Implement RtlDecompressFragment. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on a patch by Michael Müller. + +For https://bugs.winehq.org/show_bug.cgi?id=37449 --- dlls/ntdll/ntdll.spec | 2 +- - dlls/ntdll/rtl.c | 229 ++++++++++++++++++++++++++++++++++-- + dlls/ntdll/rtl.c | 214 +++++++++++++++++++++++++++++++++++- + dlls/ntdll/tests/rtl.c | 3 - dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- - 3 files changed, 224 insertions(+), 9 deletions(-) + 4 files changed, 210 insertions(+), 11 deletions(-) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index 7e95969..c79e942 100644 +index 75dc647..ca3561d 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec -@@ -511,7 +511,7 @@ +@@ -513,7 +513,7 @@ @ stdcall RtlDecodePointer(ptr) # @ stub RtlDecodeSystemPointer @ stdcall RtlDecompressBuffer(long ptr long ptr long ptr) @@ -27,33 +30,25 @@ index 7e95969..c79e942 100644 @ stub RtlDelete @ stdcall RtlDeleteAce(ptr long) diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c -index b790910..c9715df 100644 +index d9e448a..9a196d2 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c -@@ -1300,17 +1300,232 @@ NTSTATUS WINAPI RtlCompressBuffer(USHORT format, PUCHAR uncompressed, ULONG unco +@@ -1309,17 +1309,219 @@ NTSTATUS WINAPI RtlCompressBuffer(USHORT format, PUCHAR uncompressed, ULONG unco } } +/* decompress a single LZNT1 chunk */ +static PUCHAR lznt1_decompress_chunk(UCHAR *dst, ULONG dst_size, UCHAR *src, ULONG src_size) +{ -+ UCHAR *src_cur, *src_end, *dst_cur, *dst_end; ++ UCHAR *src_cur = src, *src_end = src + src_size; ++ UCHAR *dst_cur = dst, *dst_end = dst + dst_size; + ULONG displacement_bits, length_bits; + ULONG code_displacement, code_length; + WORD flags, code; + -+ src_cur = src; -+ src_end = src + src_size; -+ dst_cur = dst; -+ dst_end = dst + dst_size; -+ -+ /* Partial decompression is no error on Windows. */ + while (src_cur < src_end && dst_cur < dst_end) + { -+ /* read flags header */ + flags = 0x8000 | *src_cur++; -+ -+ /* parse following 8 entities, either uncompressed data or backwards reference */ + while ((flags & 0xFF00) && src_cur < src_end) + { + if (flags & 1) @@ -61,17 +56,18 @@ index b790910..c9715df 100644 + /* backwards reference */ + if (src_cur + sizeof(WORD) > src_end) + return NULL; ++ + code = *(WORD *)src_cur; + src_cur += sizeof(WORD); + + /* find length / displacement bits */ + for (displacement_bits = 12; displacement_bits > 4; displacement_bits--) + if ((1 << (displacement_bits - 1)) < dst_cur - dst) break; ++ + length_bits = 16 - displacement_bits; + code_length = (code & ((1 << length_bits) - 1)) + 3; + code_displacement = (code >> length_bits) + 1; + -+ /* ensure reference is valid */ + if (dst_cur < dst + code_displacement) + return NULL; + @@ -92,7 +88,6 @@ index b790910..c9715df 100644 + } + flags >>= 1; + } -+ + } + + return dst_cur; @@ -102,28 +97,23 @@ index b790910..c9715df 100644 +static NTSTATUS lznt1_decompress(UCHAR *dst, ULONG dst_size, UCHAR *src, ULONG src_size, + ULONG offset, ULONG *final_size, UCHAR *workspace) +{ -+ UCHAR *src_cur, *src_end, *dst_cur, *dst_end, *ptr; ++ UCHAR *src_cur = src, *src_end = src + src_size; ++ UCHAR *dst_cur = dst, *dst_end = dst + dst_size; + ULONG chunk_size, block_size; + WORD chunk_header; -+ -+ src_cur = src; -+ src_end = src + src_size; -+ dst_cur = dst; -+ dst_end = dst + dst_size; ++ UCHAR *ptr; + + if (src_cur + sizeof(WCHAR) > src_end) + return STATUS_BAD_COMPRESSION_BUFFER; + -+ /* skip over chunks which have a big distance (>= 0x1000) to the destination offset */ ++ /* skip over chunks which have a distance >= 0x1000 to the destination offset */ + while (offset >= 0x1000 && src_cur + sizeof(WCHAR) <= src_end) + { -+ /* read chunk header and extract size */ + chunk_header = *(WORD *)src_cur; + src_cur += sizeof(WCHAR); + if (!chunk_header) goto out; + chunk_size = (chunk_header & 0xFFF) + 1; + -+ /* ensure we have enough buffer to process chunk */ + if (src_cur + chunk_size > src_end) + return STATUS_BAD_COMPRESSION_BUFFER; + @@ -131,16 +121,14 @@ index b790910..c9715df 100644 + offset -= 0x1000; + } + -+ /* this chunk is can be included partially */ ++ /* check if a chunk is included partially */ + if (offset && src_cur + sizeof(WCHAR) <= src_end) + { -+ /* read chunk header and extract size */ + chunk_header = *(WORD *)src_cur; + src_cur += sizeof(WCHAR); + if (!chunk_header) goto out; + chunk_size = (chunk_header & 0xFFF) + 1; + -+ /* ensure we have enough buffer to process chunk */ + if (src_cur + chunk_size > src_end) + return STATUS_BAD_COMPRESSION_BUFFER; + @@ -174,19 +162,18 @@ index b790910..c9715df 100644 + src_cur += chunk_size; + } + ++ /* remaining blocks */ + while (src_cur + sizeof(WCHAR) <= src_end) + { -+ /* read chunk header and extract size */ + chunk_header = *(WORD *)src_cur; + src_cur += sizeof(WCHAR); + if (!chunk_header) goto out; + chunk_size = (chunk_header & 0xFFF) + 1; + -+ /* ensure we have enough buffer to process chunk */ + if (src_cur + chunk_size > src_end) + return STATUS_BAD_COMPRESSION_BUFFER; + -+ /* add padding if required */ ++ /* fill space with padding */ + block_size = ((dst_cur - dst) + offset) & 0xFFF; + if (block_size) + { @@ -196,7 +183,8 @@ index b790910..c9715df 100644 + memset(dst_cur, 0, block_size); + dst_cur += block_size; + } -+ else if (dst_cur >= dst_end) ++ ++ if (dst_cur >= dst_end) + goto out; + + if (chunk_header & 0x8000) @@ -224,22 +212,14 @@ index b790910..c9715df 100644 + +} + - /****************************************************************************** -- * RtlDecompressBuffer [NTDLL.@] -+ * RtlDecompressFragment [NTDLL.@] - */ --NTSTATUS WINAPI RtlDecompressBuffer(USHORT CompressionFormat, PUCHAR UncompressedBuffer, -- ULONG UncompressedBufferSize, PUCHAR CompressedBuffer, -- ULONG CompressedBufferSize, PULONG FinalUncompressedSize) ++/****************************************************************************** ++ * RtlDecompressFragment [NTDLL.@] ++ */ +NTSTATUS RtlDecompressFragment(USHORT format, PUCHAR uncompressed, ULONG uncompressed_size, + PUCHAR compressed, ULONG compressed_size, ULONG offset, + PULONG final_size, PVOID workspace) - { -- FIXME("0x%04x, %p, %u, %p, %u, %p :stub\n", CompressionFormat, UncompressedBuffer, UncompressedBufferSize, -- CompressedBuffer, CompressedBufferSize, FinalUncompressedSize); - -- return STATUS_NOT_IMPLEMENTED; -+ TRACE("0x%04x, %p, %u, %p, %u, %u, %p, %p :stub\n", format, uncompressed, ++{ ++ TRACE("0x%04x, %p, %u, %p, %u, %u, %p, %p\n", format, uncompressed, + uncompressed_size, compressed, compressed_size, offset, final_size, workspace); + + switch (format & ~COMPRESSION_ENGINE_MAXIMUM) @@ -253,25 +233,50 @@ index b790910..c9715df 100644 + return STATUS_INVALID_PARAMETER; + + default: -+ FIXME("format %d not implemented\n", format); ++ FIXME("format %u not implemented\n", format); + return STATUS_UNSUPPORTED_COMPRESSION; + } +} + + -+/****************************************************************************** -+ * RtlDecompressBuffer [NTDLL.@] -+ */ + /****************************************************************************** + * RtlDecompressBuffer [NTDLL.@] + */ +-NTSTATUS WINAPI RtlDecompressBuffer(USHORT CompressionFormat, PUCHAR UncompressedBuffer, +- ULONG UncompressedBufferSize, PUCHAR CompressedBuffer, +- ULONG CompressedBufferSize, PULONG FinalUncompressedSize) +NTSTATUS WINAPI RtlDecompressBuffer(USHORT format, PUCHAR uncompressed, ULONG uncompressed_size, + PUCHAR compressed, ULONG compressed_size, PULONG final_size) -+{ + { +- FIXME("0x%04x, %p, %u, %p, %u, %p :stub\n", CompressionFormat, UncompressedBuffer, UncompressedBufferSize, +- CompressedBuffer, CompressedBufferSize, FinalUncompressedSize); ++ TRACE("0x%04x, %p, %u, %p, %u, %p\n", format, uncompressed, ++ uncompressed_size, compressed, compressed_size, final_size); + +- return STATUS_NOT_IMPLEMENTED; + return RtlDecompressFragment(format, uncompressed, uncompressed_size, + compressed, compressed_size, 0, final_size, NULL); } /*********************************************************************** +diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c +index c6a7023..99fd413 100644 +--- a/dlls/ntdll/tests/rtl.c ++++ b/dlls/ntdll/tests/rtl.c +@@ -1663,11 +1663,8 @@ static void test_RtlCompressBuffer(void) + memset(buf2, 0x11, sizeof(buf2)); + status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf2, sizeof(buf2), + buf1, buf_size, &final_size); +- todo_wine + ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); +- todo_wine + ok(final_size == sizeof(test_buffer), "got wrong final_size %u\n", final_size); +- todo_wine + ok(!memcmp(buf2, test_buffer, sizeof(test_buffer)), "got wrong decoded data\n"); + ok(buf2[sizeof(test_buffer)] == 0x11, "too many bytes written\n"); + diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec -index 4ead907..bfc3c59 100644 +index 11d1c62..0bb7d04 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -977,7 +977,7 @@ @@ -284,5 +289,5 @@ index 4ead907..bfc3c59 100644 @ stdcall RtlDeleteAce(ptr long) ntdll.RtlDeleteAce @ stdcall RtlDeleteAtomFromAtomTable(ptr long) ntdll.RtlDeleteAtomFromAtomTable -- -2.1.3 +2.4.5 diff --git a/patches/ntdll-LZNT1_Compression/0001-ntdll-Implement-semi-stub-for-RtlGetCompressionWorkS.patch b/patches/ntdll-LZNT1_Compression/0001-ntdll-Implement-semi-stub-for-RtlGetCompressionWorkS.patch deleted file mode 100644 index 60ea5f8b..00000000 --- a/patches/ntdll-LZNT1_Compression/0001-ntdll-Implement-semi-stub-for-RtlGetCompressionWorkS.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 8f2dbbc47749542a135c5410c94097d8b14e0a84 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Thu, 30 Oct 2014 17:19:42 +0100 -Subject: ntdll: Implement semi-stub for RtlGetCompressionWorkSpaceSize. - ---- - dlls/ntdll/rtl.c | 26 ++++++++++++++++++++------ - include/winnt.h | 6 ++++++ - 2 files changed, 26 insertions(+), 6 deletions(-) - -diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c -index 8f6f386..884a14a 100644 ---- a/dlls/ntdll/rtl.c -+++ b/dlls/ntdll/rtl.c -@@ -1215,14 +1215,28 @@ PSLIST_ENTRY WINAPI RtlInterlockedPushListSList(PSLIST_HEADER list, PSLIST_ENTRY - /****************************************************************************** - * RtlGetCompressionWorkSpaceSize [NTDLL.@] - */ --NTSTATUS WINAPI RtlGetCompressionWorkSpaceSize(USHORT CompressionFormatAndEngine, -- PULONG CompressBufferWorkSpaceSize, -- PULONG CompressFragmentWorkSpaceSize) -+NTSTATUS WINAPI RtlGetCompressionWorkSpaceSize(USHORT format, PULONG compress_workspace, -+ PULONG decompress_workspace) - { -- FIXME("0x%04x, %p, %p: stub!\n", CompressionFormatAndEngine, CompressBufferWorkSpaceSize, -- CompressFragmentWorkSpaceSize); -+ FIXME("0x%04x, %p, %p: semi-stub\n", format, compress_workspace, decompress_workspace); - -- return STATUS_NOT_IMPLEMENTED; -+ switch (format & ~COMPRESSION_ENGINE_MAXIMUM) -+ { -+ case COMPRESSION_FORMAT_LZNT1: -+ if (compress_workspace) -+ *compress_workspace = 16; /* FIXME */ -+ if (decompress_workspace) -+ *decompress_workspace = 0x1000; -+ return STATUS_SUCCESS; -+ -+ case COMPRESSION_FORMAT_NONE: -+ case COMPRESSION_FORMAT_DEFAULT: -+ return STATUS_INVALID_PARAMETER; -+ -+ default: -+ FIXME("format %d not implemented\n", format); -+ return STATUS_UNSUPPORTED_COMPRESSION; -+ } - } - - /****************************************************************************** -diff --git a/include/winnt.h b/include/winnt.h -index 709a93f..401e3ad 100644 ---- a/include/winnt.h -+++ b/include/winnt.h -@@ -4722,6 +4722,12 @@ typedef struct _QUOTA_LIMITS_EX { - #define FILE_256_BYTE_ALIGNMENT 0x000000ff - #define FILE_512_BYTE_ALIGNMENT 0x000001ff - -+#define COMPRESSION_FORMAT_NONE 0 -+#define COMPRESSION_FORMAT_DEFAULT 1 -+#define COMPRESSION_FORMAT_LZNT1 2 -+#define COMPRESSION_ENGINE_STANDARD 0 -+#define COMPRESSION_ENGINE_MAXIMUM 256 -+ - #define MAILSLOT_NO_MESSAGE ((DWORD)-1) - #define MAILSLOT_WAIT_FOREVER ((DWORD)-1) - --- -2.1.2 - diff --git a/patches/ntdll-LZNT1_Compression/0002-ntdll-Implement-semi-stub-for-RtlCompressBuffer.patch b/patches/ntdll-LZNT1_Compression/0002-ntdll-Implement-semi-stub-for-RtlCompressBuffer.patch deleted file mode 100644 index e46fcc22..00000000 --- a/patches/ntdll-LZNT1_Compression/0002-ntdll-Implement-semi-stub-for-RtlCompressBuffer.patch +++ /dev/null @@ -1,90 +0,0 @@ -From e487c879736038053aac64aa728ba35c78888e71 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Thu, 30 Oct 2014 17:24:26 +0100 -Subject: ntdll: Implement semi-stub for RtlCompressBuffer. - ---- - dlls/ntdll/rtl.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++-------- - 1 file changed, 54 insertions(+), 8 deletions(-) - -diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c -index 884a14a..b790910 100644 ---- a/dlls/ntdll/rtl.c -+++ b/dlls/ntdll/rtl.c -@@ -1239,19 +1239,65 @@ NTSTATUS WINAPI RtlGetCompressionWorkSpaceSize(USHORT format, PULONG compress_wo - } - } - -+/* 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_end, *dst_cur, *dst_end; -+ ULONG block_size; -+ -+ src_cur = src; -+ src_end = src + src_size; -+ dst_cur = dst; -+ dst_end = dst + dst_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 %d not implemented\n", format); -+ return STATUS_UNSUPPORTED_COMPRESSION; -+ } - } - - /****************************************************************************** --- -2.1.2 - diff --git a/patches/ntdll-LZNT1_Compression/0002-ntdll-tests-Add-tests-for-RtlDecompressBuffer.patch b/patches/ntdll-LZNT1_Compression/0002-ntdll-tests-Add-tests-for-RtlDecompressBuffer.patch new file mode 100644 index 00000000..48e825d9 --- /dev/null +++ b/patches/ntdll-LZNT1_Compression/0002-ntdll-tests-Add-tests-for-RtlDecompressBuffer.patch @@ -0,0 +1,389 @@ +From 2609aa20f4eea473a574d19d5a7d60598a8cc98e Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Thu, 9 Jul 2015 03:07:40 +0200 +Subject: ntdll/tests: Add tests for RtlDecompressBuffer. + +--- + dlls/ntdll/tests/rtl.c | 361 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 361 insertions(+) + +diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c +index 99fd413..a1b9327 100644 +--- a/dlls/ntdll/tests/rtl.c ++++ b/dlls/ntdll/tests/rtl.c +@@ -1717,6 +1717,366 @@ static void test_RtlGetCompressionWorkSpaceSize(void) + ok(decompress_workspace == 0x1000, "got wrong decompress_workspace %u\n", decompress_workspace); + } + ++/* helper for test_RtlDecompressBuffer, checks if a chunk is incomplete */ ++static BOOL is_incomplete_chunk(const UCHAR *compressed, ULONG compressed_size, BOOL check_all) ++{ ++ ULONG chunk_size; ++ ++ if (compressed_size <= sizeof(WORD)) ++ return TRUE; ++ ++ while (compressed_size >= sizeof(WORD)) ++ { ++ chunk_size = (*(WORD *)compressed & 0xFFF) + 1; ++ if (compressed_size < sizeof(WORD) + chunk_size) ++ return TRUE; ++ if (!check_all) ++ break; ++ compressed += sizeof(WORD) + chunk_size; ++ compressed_size -= sizeof(WORD) + chunk_size; ++ } ++ ++ return FALSE; ++} ++ ++#define DECOMPRESS_BROKEN_FRAGMENT 1 /* < Win 7 */ ++#define DECOMPRESS_BROKEN_TRUNCATED 2 /* broken on all machines */ ++ ++static void test_RtlDecompressBuffer(void) ++{ ++ static const struct ++ { ++ UCHAR compressed[32]; ++ ULONG compressed_size; ++ NTSTATUS status; ++ UCHAR uncompressed[32]; ++ ULONG uncompressed_size; ++ DWORD broken_flags; ++ } ++ test_lznt[] = ++ { ++ /* 4 byte uncompressed chunk */ ++ { ++ {0x03, 0x30, 'W', 'i', 'n', 'e'}, ++ 6, ++ STATUS_SUCCESS, ++ "Wine", ++ 4, ++ DECOMPRESS_BROKEN_FRAGMENT ++ }, ++ /* 8 byte uncompressed chunk */ ++ { ++ {0x07, 0x30, 'W', 'i', 'n', 'e', 'W', 'i', 'n', 'e'}, ++ 10, ++ STATUS_SUCCESS, ++ "WineWine", ++ 8, ++ DECOMPRESS_BROKEN_FRAGMENT ++ }, ++ /* 4 byte compressed chunk */ ++ { ++ {0x04, 0xB0, 0x00, 'W', 'i', 'n', 'e'}, ++ 7, ++ STATUS_SUCCESS, ++ "Wine", ++ 4 ++ }, ++ /* 8 byte compressed chunk */ ++ { ++ {0x08, 0xB0, 0x00, 'W', 'i', 'n', 'e', 'W', 'i', 'n', 'e'}, ++ 11, ++ STATUS_SUCCESS, ++ "WineWine", ++ 8 ++ }, ++ /* compressed chunk using backwards reference */ ++ { ++ {0x06, 0xB0, 0x10, 'W', 'i', 'n', 'e', 0x01, 0x30}, ++ 9, ++ STATUS_SUCCESS, ++ "WineWine", ++ 8, ++ DECOMPRESS_BROKEN_TRUNCATED ++ }, ++ /* compressed chunk using backwards reference with length > bytes_read */ ++ { ++ {0x06, 0xB0, 0x10, 'W', 'i', 'n', 'e', 0x05, 0x30}, ++ 9, ++ STATUS_SUCCESS, ++ "WineWineWine", ++ 12, ++ DECOMPRESS_BROKEN_TRUNCATED ++ }, ++ /* same as above, but unused bits != 0 */ ++ { ++ {0x06, 0xB0, 0x30, 'W', 'i', 'n', 'e', 0x01, 0x30}, ++ 9, ++ STATUS_SUCCESS, ++ "WineWine", ++ 8, ++ DECOMPRESS_BROKEN_TRUNCATED ++ }, ++ /* compressed chunk without backwards reference and unused bits != 0 */ ++ { ++ {0x01, 0xB0, 0x02, 'W'}, ++ 4, ++ STATUS_SUCCESS, ++ "W", ++ 1 ++ }, ++ /* termination sequence after first chunk */ ++ { ++ {0x03, 0x30, 'W', 'i', 'n', 'e', 0x00, 0x00, 0x03, 0x30, 'W', 'i', 'n', 'e'}, ++ 14, ++ STATUS_SUCCESS, ++ "Wine", ++ 4, ++ DECOMPRESS_BROKEN_FRAGMENT ++ }, ++ /* compressed chunk using backwards reference with 4 bit offset, 12 bit length */ ++ { ++ {0x14, 0xB0, 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', ++ 0x00, 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', ++ 0x01, 0x01, 0xF0}, ++ 23, ++ STATUS_SUCCESS, ++ "ABCDEFGHIJKLMNOPABCD", ++ 20, ++ DECOMPRESS_BROKEN_TRUNCATED ++ }, ++ /* compressed chunk using backwards reference with 5 bit offset, 11 bit length */ ++ { ++ {0x15, 0xB0, 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', ++ 0x00, 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', ++ 0x02, 'A', 0x00, 0x78}, ++ 24, ++ STATUS_SUCCESS, ++ "ABCDEFGHIJKLMNOPABCD", ++ 20, ++ DECOMPRESS_BROKEN_TRUNCATED ++ }, ++ /* uncompressed chunk with invalid magic */ ++ { ++ {0x03, 0x20, 'W', 'i', 'n', 'e'}, ++ 6, ++ STATUS_SUCCESS, ++ "Wine", ++ 4, ++ DECOMPRESS_BROKEN_FRAGMENT ++ }, ++ /* compressed chunk with invalid magic */ ++ { ++ {0x04, 0xA0, 0x00, 'W', 'i', 'n', 'e'}, ++ 7, ++ STATUS_SUCCESS, ++ "Wine", ++ 4 ++ }, ++ /* garbage byte after end of buffer */ ++ { ++ {0x00, 0xB0, 0x02, 0x01}, ++ 4, ++ STATUS_SUCCESS, ++ "", ++ 0 ++ }, ++ /* empty compressed chunk */ ++ { ++ {0x00, 0xB0, 0x00}, ++ 3, ++ STATUS_SUCCESS, ++ "", ++ 0 ++ }, ++ /* empty compressed chunk with unused bits != 0 */ ++ { ++ {0x00, 0xB0, 0x01}, ++ 3, ++ STATUS_SUCCESS, ++ "", ++ 0 ++ }, ++ /* empty input buffer */ ++ { ++ {}, ++ 0, ++ STATUS_BAD_COMPRESSION_BUFFER, ++ }, ++ /* incomplete chunk header */ ++ { ++ {0x01}, ++ 1, ++ STATUS_BAD_COMPRESSION_BUFFER ++ }, ++ /* incomplete chunk header */ ++ { ++ {0x00, 0x30}, ++ 2, ++ STATUS_BAD_COMPRESSION_BUFFER ++ }, ++ /* compressed chunk with invalid backwards reference */ ++ { ++ {0x06, 0xB0, 0x10, 'W', 'i', 'n', 'e', 0x05, 0x40}, ++ 9, ++ STATUS_BAD_COMPRESSION_BUFFER ++ }, ++ /* compressed chunk with incomplete backwards reference */ ++ { ++ {0x05, 0xB0, 0x10, 'W', 'i', 'n', 'e', 0x05}, ++ 8, ++ STATUS_BAD_COMPRESSION_BUFFER ++ }, ++ /* incomplete uncompressed chunk */ ++ { ++ {0x07, 0x30, 'W', 'i', 'n', 'e'}, ++ 6, ++ STATUS_BAD_COMPRESSION_BUFFER ++ }, ++ /* incomplete compressed chunk */ ++ { ++ {0x08, 0xB0, 0x00, 'W', 'i', 'n', 'e'}, ++ 7, ++ STATUS_BAD_COMPRESSION_BUFFER ++ }, ++ /* two compressed chunks, the second one incomplete */ ++ { ++ {0x00, 0xB0, 0x02, 0x00, 0xB0}, ++ 5, ++ STATUS_BAD_COMPRESSION_BUFFER, ++ } ++ }; ++ ++ static UCHAR buf[0x2000]; ++ NTSTATUS status; ++ ULONG final_size; ++ int i; ++ ++ if (!pRtlDecompressBuffer) ++ { ++ win_skip("RtlDecompressBuffer is not available\n"); ++ return; ++ } ++ ++ /* test compression format / engine */ ++ final_size = 0xdeadbeef; ++ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_NONE, buf, sizeof(buf), test_lznt[0].compressed, ++ test_lznt[0].compressed_size, &final_size); ++ 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 = pRtlDecompressBuffer(COMPRESSION_FORMAT_DEFAULT, buf, sizeof(buf), test_lznt[0].compressed, ++ test_lznt[0].compressed_size, &final_size); ++ 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 = pRtlDecompressBuffer(0xFF, buf, sizeof(buf), test_lznt[0].compressed, ++ test_lznt[0].compressed_size, &final_size); ++ ok(status == STATUS_UNSUPPORTED_COMPRESSION, "got wrong status 0x%08x\n", status); ++ ok(final_size == 0xdeadbeef, "got wrong final_size %u\n", final_size); ++ ++ /* regular tests for RtlDecompressBuffer */ ++ for (i = 0; i < sizeof(test_lznt) / sizeof(test_lznt[0]); i++) ++ { ++ trace("Running test %d (compressed_size=%u, uncompressed_size=%u, status=0x%08x)\n", ++ i, test_lznt[i].compressed_size, test_lznt[i].uncompressed_size, test_lznt[i].status); ++ ++ /* test with very big buffer */ ++ final_size = 0xdeadbeef; ++ memset(buf, 0x11, sizeof(buf)); ++ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, ++ test_lznt[i].compressed_size, &final_size); ++ ok(status == test_lznt[i].status || broken(status == STATUS_BAD_COMPRESSION_BUFFER && ++ (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT)), "%d: got wrong status 0x%08x\n", i, status); ++ if (!status) ++ { ++ ok(final_size == test_lznt[i].uncompressed_size, ++ "%d: got wrong final_size %u\n", i, final_size); ++ ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size), ++ "%d: got wrong decoded data\n", i); ++ ok(buf[test_lznt[i].uncompressed_size] == 0x11, ++ "%d: buf[%u] was modified\n", i, test_lznt[i].uncompressed_size); ++ } ++ ++ /* test that modifier for compression engine is ignored */ ++ final_size = 0xdeadbeef; ++ memset(buf, 0x11, sizeof(buf)); ++ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM, buf, sizeof(buf), ++ test_lznt[i].compressed, test_lznt[i].compressed_size, &final_size); ++ ok(status == test_lznt[i].status || broken(status == STATUS_BAD_COMPRESSION_BUFFER && ++ (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT)), "%d: got wrong status 0x%08x\n", i, status); ++ if (!status) ++ { ++ ok(final_size == test_lznt[i].uncompressed_size, ++ "%d: got wrong final_size %u\n", i, final_size); ++ ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size), ++ "%d: got wrong decoded data\n", i); ++ ok(buf[test_lznt[i].uncompressed_size] == 0x11, ++ "%d: buf[%u] was modified\n", i, test_lznt[i].uncompressed_size); ++ } ++ ++ /* test with expected output size */ ++ if (test_lznt[i].uncompressed_size > 0) ++ { ++ final_size = 0xdeadbeef; ++ memset(buf, 0x11, sizeof(buf)); ++ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, test_lznt[i].uncompressed_size, ++ test_lznt[i].compressed, test_lznt[i].compressed_size, &final_size); ++ ok(status == test_lznt[i].status, "%d: got wrong status 0x%08x\n", i, status); ++ if (!status) ++ { ++ ok(final_size == test_lznt[i].uncompressed_size, ++ "%d: got wrong final_size %u\n", i, final_size); ++ ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size), ++ "%d: got wrong decoded data\n", i); ++ ok(buf[test_lznt[i].uncompressed_size] == 0x11, ++ "%d: buf[%u] was modified\n", i, test_lznt[i].uncompressed_size); ++ } ++ } ++ ++ /* test with smaller output size */ ++ if (test_lznt[i].uncompressed_size > 1) ++ { ++ final_size = 0xdeadbeef; ++ memset(buf, 0x11, sizeof(buf)); ++ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, test_lznt[i].uncompressed_size - 1, ++ test_lznt[i].compressed, test_lznt[i].compressed_size, &final_size); ++ if (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_TRUNCATED) ++ todo_wine ++ ok(status == STATUS_BAD_COMPRESSION_BUFFER, "%d: got wrong status 0x%08x\n", i, status); ++ else ++ ok(status == test_lznt[i].status, "%d: got wrong status 0x%08x\n", i, status); ++ if (!status) ++ { ++ ok(final_size == test_lznt[i].uncompressed_size - 1, ++ "%d: got wrong final_size %u\n", i, final_size); ++ ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size - 1), ++ "%d: got wrong decoded data\n", i); ++ ok(buf[test_lznt[i].uncompressed_size - 1] == 0x11, ++ "%d: buf[%u] was modified\n", i, test_lznt[i].uncompressed_size - 1); ++ } ++ } ++ ++ /* test with zero output size */ ++ final_size = 0xdeadbeef; ++ memset(buf, 0x11, sizeof(buf)); ++ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, 0, test_lznt[i].compressed, ++ test_lznt[i].compressed_size, &final_size); ++ if (is_incomplete_chunk(test_lznt[i].compressed, test_lznt[i].compressed_size, FALSE)) ++ ok(status == STATUS_BAD_COMPRESSION_BUFFER, "%d: got wrong status 0x%08x\n", i, status); ++ else ++ { ++ ok(status == STATUS_SUCCESS, "%d: got wrong status 0x%08x\n", i, status); ++ ok(final_size == 0, "%d: got wrong final_size %u\n", i, final_size); ++ ok(buf[0] == 0x11, "%d: buf[0] was modified\n", i); ++ } ++ } ++} ++ ++#undef DECOMPRESS_BROKEN_FRAGMENT ++#undef DECOMPRESS_BROKEN_TRUNCATED ++ + START_TEST(rtl) + { + InitFunctionPtrs(); +@@ -1745,4 +2105,5 @@ START_TEST(rtl) + test_LdrLockLoaderLock(); + test_RtlCompressBuffer(); + test_RtlGetCompressionWorkSpaceSize(); ++ test_RtlDecompressBuffer(); + } +-- +2.4.5 + diff --git a/patches/ntdll-LZNT1_Compression/0003-ntdll-tests-Add-tests-for-RtlDecompressFragment.patch b/patches/ntdll-LZNT1_Compression/0003-ntdll-tests-Add-tests-for-RtlDecompressFragment.patch new file mode 100644 index 00000000..99515e13 --- /dev/null +++ b/patches/ntdll-LZNT1_Compression/0003-ntdll-tests-Add-tests-for-RtlDecompressFragment.patch @@ -0,0 +1,141 @@ +From 6546dabdc504eb340167404ca66364a536e65cdc Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Thu, 9 Jul 2015 03:08:09 +0200 +Subject: ntdll/tests: Add tests for RtlDecompressFragment. + +--- + dlls/ntdll/tests/rtl.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 89 insertions(+), 4 deletions(-) + +diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c +index a1b9327..4903790 100644 +--- a/dlls/ntdll/tests/rtl.c ++++ b/dlls/ntdll/tests/rtl.c +@@ -94,6 +94,7 @@ static NTSTATUS (WINAPI *pLdrLockLoaderLock)(ULONG, ULONG*, ULONG_PTR*); + static NTSTATUS (WINAPI *pLdrUnlockLoaderLock)(ULONG, ULONG_PTR); + static NTSTATUS (WINAPI *pRtlGetCompressionWorkSpaceSize)(USHORT, PULONG, PULONG); + static NTSTATUS (WINAPI *pRtlDecompressBuffer)(USHORT, PUCHAR, ULONG, const UCHAR*, ULONG, PULONG); ++static NTSTATUS (WINAPI *pRtlDecompressFragment)(USHORT, PUCHAR, ULONG, const UCHAR*, ULONG, ULONG, PULONG, PVOID); + static NTSTATUS (WINAPI *pRtlCompressBuffer)(USHORT, const UCHAR*, ULONG, PUCHAR, ULONG, ULONG, PULONG, PVOID); + + static HMODULE hkernel32 = 0; +@@ -144,6 +145,7 @@ static void InitFunctionPtrs(void) + pLdrUnlockLoaderLock = (void *)GetProcAddress(hntdll, "LdrUnlockLoaderLock"); + pRtlGetCompressionWorkSpaceSize = (void *)GetProcAddress(hntdll, "RtlGetCompressionWorkSpaceSize"); + pRtlDecompressBuffer = (void *)GetProcAddress(hntdll, "RtlDecompressBuffer"); ++ pRtlDecompressFragment = (void *)GetProcAddress(hntdll, "RtlDecompressFragment"); + pRtlCompressBuffer = (void *)GetProcAddress(hntdll, "RtlCompressBuffer"); + } + hkernel32 = LoadLibraryA("kernel32.dll"); +@@ -1946,14 +1948,14 @@ static void test_RtlDecompressBuffer(void) + } + }; + +- static UCHAR buf[0x2000]; +- NTSTATUS status; ++ static UCHAR buf[0x2000], workspace[0x1000]; ++ NTSTATUS status, expected_status; + ULONG final_size; + int i; + +- if (!pRtlDecompressBuffer) ++ if (!pRtlDecompressBuffer || !pRtlDecompressFragment) + { +- win_skip("RtlDecompressBuffer is not available\n"); ++ win_skip("RtlDecompressBuffer or RtlDecompressFragment is not available\n"); + return; + } + +@@ -2071,6 +2073,89 @@ static void test_RtlDecompressBuffer(void) + ok(final_size == 0, "%d: got wrong final_size %u\n", i, final_size); + ok(buf[0] == 0x11, "%d: buf[0] was modified\n", i); + } ++ ++ /* test RtlDecompressFragment with offset = 0 */ ++ final_size = 0xdeadbeef; ++ memset(buf, 0x11, sizeof(buf)); ++ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, ++ test_lznt[i].compressed_size, 0, &final_size, workspace); ++ if (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT) ++ todo_wine ++ ok(status == STATUS_BAD_COMPRESSION_BUFFER, "%d: got wrong status 0x%08x\n", i, status); ++ else ++ ok(status == test_lznt[i].status, "%d: got wrong status 0x%08x\n", i, status); ++ if (!status) ++ { ++ ok(final_size == test_lznt[i].uncompressed_size, ++ "%d: got wrong final_size %u\n", i, final_size); ++ ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size), ++ "%d: got wrong decoded data\n", i); ++ ok(buf[test_lznt[i].uncompressed_size] == 0x11, ++ "%d: buf[%u] was modified\n", i, test_lznt[i].uncompressed_size); ++ } ++ ++ /* test RtlDecompressFragment with offset = 1 */ ++ final_size = 0xdeadbeef; ++ memset(buf, 0x11, sizeof(buf)); ++ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, ++ test_lznt[i].compressed_size, 1, &final_size, workspace); ++ if (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT) ++ todo_wine ++ ok(status == STATUS_BAD_COMPRESSION_BUFFER, "%d: got wrong status 0x%08x\n", i, status); ++ else ++ ok(status == test_lznt[i].status, "%d: got wrong status 0x%08x\n", i, status); ++ if (!status) ++ { ++ if (test_lznt[i].uncompressed_size == 0) ++ { ++ todo_wine ++ ok(final_size == 4095, "%d: got wrong final_size %u\n", i, final_size); ++ /* Buffer doesn't contain any useful value on Windows */ ++ ok(buf[4095] == 0x11, "%d: buf[4095] was modified\n", i); ++ } ++ else ++ { ++ ok(final_size == test_lznt[i].uncompressed_size - 1, ++ "%d: got wrong final_size %u\n", i, final_size); ++ ok(!memcmp(buf, test_lznt[i].uncompressed + 1, test_lznt[i].uncompressed_size - 1), ++ "%d: got wrong decoded data\n", i); ++ ok(buf[test_lznt[i].uncompressed_size - 1] == 0x11, ++ "%d: buf[%u] was modified\n", i, test_lznt[i].uncompressed_size - 1); ++ } ++ } ++ ++ /* test RtlDecompressFragment with offset = 4095 */ ++ final_size = 0xdeadbeef; ++ memset(buf, 0x11, sizeof(buf)); ++ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, ++ test_lznt[i].compressed_size, 4095, &final_size, workspace); ++ if (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT) ++ todo_wine ++ ok(status == STATUS_BAD_COMPRESSION_BUFFER, "%d: got wrong status 0x%08x\n", i, status); ++ else ++ ok(status == test_lznt[i].status, "%d: got wrong status 0x%08x\n", i, status); ++ if (!status) ++ { ++ todo_wine ++ ok(final_size == 1, "%d: got wrong final_size %u\n", i, final_size); ++ todo_wine ++ ok(buf[0] == 0, "%d: padding is not zero\n", i); ++ ok(buf[1] == 0x11, "%d: buf[1] was modified\n", i); ++ } ++ ++ /* test RtlDecompressFragment with offset = 4096 */ ++ final_size = 0xdeadbeef; ++ memset(buf, 0x11, sizeof(buf)); ++ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, ++ test_lznt[i].compressed_size, 4096, &final_size, workspace); ++ expected_status = is_incomplete_chunk(test_lznt[i].compressed, test_lznt[i].compressed_size, TRUE) ? ++ test_lznt[i].status : STATUS_SUCCESS; ++ ok(status == expected_status, "%d: got wrong status 0x%08x, expected 0x%08x\n", i, status, expected_status); ++ if (!status) ++ { ++ ok(final_size == 0, "%d: got wrong final_size %u\n", i, final_size); ++ ok(buf[0] == 0x11, "%d: buf[4096] was modified\n", i); ++ } + } + } + +-- +2.4.5 + diff --git a/patches/ntdll-LZNT1_Compression/0004-ntdll-tests-Add-tests-for-Rtl-Decompress-Compress-Bu.patch b/patches/ntdll-LZNT1_Compression/0004-ntdll-tests-Add-tests-for-Rtl-Decompress-Compress-Bu.patch deleted file mode 100644 index aa490887..00000000 --- a/patches/ntdll-LZNT1_Compression/0004-ntdll-tests-Add-tests-for-Rtl-Decompress-Compress-Bu.patch +++ /dev/null @@ -1,783 +0,0 @@ -From ec029295815e271cfaf193997cdde3cf53df4a3b Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Thu, 30 Oct 2014 17:41:11 +0100 -Subject: ntdll/tests: Add tests for Rtl[Decompress|Compress]Buffer and - RtlGetCompressionWorkSpaceSize. - ---- - dlls/ntdll/tests/rtl.c | 740 +++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 740 insertions(+) - -diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c -index e8eb04a..2f6c421 100644 ---- a/dlls/ntdll/tests/rtl.c -+++ b/dlls/ntdll/tests/rtl.c -@@ -92,6 +92,10 @@ static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ - static NTSTATUS (WINAPI *pLdrAddRefDll)(ULONG, HMODULE); - static NTSTATUS (WINAPI *pLdrLockLoaderLock)(ULONG, ULONG*, ULONG_PTR*); - static NTSTATUS (WINAPI *pLdrUnlockLoaderLock)(ULONG, ULONG_PTR); -+static NTSTATUS (WINAPI *pRtlGetCompressionWorkSpaceSize)(USHORT, PULONG, PULONG); -+static NTSTATUS (WINAPI *pRtlDecompressBuffer)(USHORT, PUCHAR, ULONG, const UCHAR*, ULONG, PULONG); -+static NTSTATUS (WINAPI *pRtlDecompressFragment)(USHORT, PUCHAR, ULONG, const UCHAR*, ULONG, ULONG, PULONG, PVOID); -+static NTSTATUS (WINAPI *pRtlCompressBuffer)(USHORT, const UCHAR*, ULONG, PUCHAR, ULONG, ULONG, PULONG, PVOID); - - static HMODULE hkernel32 = 0; - static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); -@@ -139,6 +143,10 @@ static void InitFunctionPtrs(void) - pLdrAddRefDll = (void *)GetProcAddress(hntdll, "LdrAddRefDll"); - pLdrLockLoaderLock = (void *)GetProcAddress(hntdll, "LdrLockLoaderLock"); - pLdrUnlockLoaderLock = (void *)GetProcAddress(hntdll, "LdrUnlockLoaderLock"); -+ pRtlGetCompressionWorkSpaceSize = (void *)GetProcAddress(hntdll, "RtlGetCompressionWorkSpaceSize"); -+ pRtlDecompressBuffer = (void *)GetProcAddress(hntdll, "RtlDecompressBuffer"); -+ pRtlDecompressFragment = (void *)GetProcAddress(hntdll, "RtlDecompressFragment"); -+ pRtlCompressBuffer = (void *)GetProcAddress(hntdll, "RtlCompressBuffer"); - } - hkernel32 = LoadLibraryA("kernel32.dll"); - ok(hkernel32 != 0, "LoadLibrary failed\n"); -@@ -1599,6 +1607,735 @@ static void test_LdrLockLoaderLock(void) - pLdrUnlockLoaderLock(0, magic); - } - -+static void test_RtlGetCompressionWorkSpaceSize(void) -+{ -+ ULONG compress_workspace, decompress_workspace; -+ NTSTATUS status; -+ -+ if (!pRtlGetCompressionWorkSpaceSize) -+ { -+ win_skip("RtlGetCompressionWorkSpaceSize is not available\n"); -+ return; -+ } -+ -+ status = pRtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_NONE, &compress_workspace, -+ &decompress_workspace); -+ ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08x\n", status); -+ -+ status = pRtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_DEFAULT, &compress_workspace, -+ &decompress_workspace); -+ ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08x\n", status); -+ -+ status = pRtlGetCompressionWorkSpaceSize(0xFF, &compress_workspace, &decompress_workspace); -+ ok(status == STATUS_UNSUPPORTED_COMPRESSION, "got wrong status 0x%08x\n", status); -+ -+ compress_workspace = decompress_workspace = 0xdeadbeef; -+ status = pRtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_LZNT1, &compress_workspace, -+ &decompress_workspace); -+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ ok(compress_workspace != 0, "got wrong compress_workspace %d\n", compress_workspace); -+ ok(decompress_workspace == 0x1000, "got wrong decompress_workspace %d\n", decompress_workspace); -+ -+ compress_workspace = decompress_workspace = 0xdeadbeef; -+ status = pRtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM, -+ &compress_workspace, &decompress_workspace); -+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ ok(compress_workspace != 0, "got wrong compress_workspace %d\n", compress_workspace); -+ ok(decompress_workspace == 0x1000, "got wrong decompress_workspace %d\n", decompress_workspace); -+} -+ -+/* helper for test_RtlDecompressBuffer, checks if a chunk is incomplete */ -+static BOOL is_incomplete_chunk(const UCHAR *compressed, ULONG compressed_size, BOOL check_all) -+{ -+ ULONG chunk_size; -+ if (compressed_size <= sizeof(WORD)) -+ return TRUE; -+ while (compressed_size >= sizeof(WORD)) -+ { -+ chunk_size = (*(WORD *)compressed & 0xFFF) + 1; -+ if (compressed_size < sizeof(WORD) + chunk_size) -+ return TRUE; -+ if (!check_all) -+ break; -+ compressed += sizeof(WORD) + chunk_size; -+ compressed_size -= sizeof(WORD) + chunk_size; -+ } -+ return FALSE; -+} -+ -+#define DECOMPRESS_BROKEN_TRUNCATED 1 -+#define DECOMPRESS_BROKEN_FRAGMENT0 2 -+#define DECOMPRESS_BROKEN_FRAGMENT1 4 -+#define DECOMPRESS_BROKEN_FRAGMENT4095 8 -+ -+static void test_RtlDecompressBuffer(void) -+{ -+ static const UCHAR test_multiple_chunks[] = {0x03, 0x30, 'W', 'i', 'n', 'e', -+ 0x03, 0x30, 'W', 'i', 'n', 'e'}; -+ static const struct -+ { -+ UCHAR compressed[32]; -+ ULONG compressed_size; -+ NTSTATUS status; -+ UCHAR uncompressed[32]; -+ ULONG uncompressed_size; -+ DWORD broken_flags; -+ } -+ test_lznt[] = -+ { -+ /* 4 byte uncompressed chunk */ -+ { -+ {0x03, 0x30, 'W', 'i', 'n', 'e'}, -+ 6, -+ STATUS_SUCCESS, -+ "Wine", -+ 4, -+ DECOMPRESS_BROKEN_FRAGMENT4095 | -+ DECOMPRESS_BROKEN_FRAGMENT1 | -+ DECOMPRESS_BROKEN_FRAGMENT0 -+ }, -+ /* 8 byte uncompressed chunk */ -+ { -+ {0x07, 0x30, 'W', 'i', 'n', 'e', 'W', 'i', 'n', 'e'}, -+ 10, -+ STATUS_SUCCESS, -+ "WineWine", -+ 8, -+ DECOMPRESS_BROKEN_FRAGMENT4095 | -+ DECOMPRESS_BROKEN_FRAGMENT1 | -+ DECOMPRESS_BROKEN_FRAGMENT0 -+ }, -+ /* 4 byte compressed chunk */ -+ { -+ {0x04, 0xB0, 0x00, 'W', 'i', 'n', 'e'}, -+ 7, -+ STATUS_SUCCESS, -+ "Wine", -+ 4 -+ }, -+ /* 8 byte compressed chunk */ -+ { -+ {0x08, 0xB0, 0x00, 'W', 'i', 'n', 'e', 'W', 'i', 'n', 'e'}, -+ 11, -+ STATUS_SUCCESS, -+ "WineWine", -+ 8 -+ }, -+ /* compressed chunk using backwards reference */ -+ { -+ {0x06, 0xB0, 0x10, 'W', 'i', 'n', 'e', 0x01, 0x30}, -+ 9, -+ STATUS_SUCCESS, -+ "WineWine", -+ 8, -+ DECOMPRESS_BROKEN_TRUNCATED -+ }, -+ /* compressed chunk using backwards reference with length > bytes_read */ -+ { -+ {0x06, 0xB0, 0x10, 'W', 'i', 'n', 'e', 0x05, 0x30}, -+ 9, -+ STATUS_SUCCESS, -+ "WineWineWine", -+ 12, -+ DECOMPRESS_BROKEN_TRUNCATED -+ }, -+ /* same as above, but unused bits != 0 */ -+ { -+ {0x06, 0xB0, 0x30, 'W', 'i', 'n', 'e', 0x01, 0x30}, -+ 9, -+ STATUS_SUCCESS, -+ "WineWine", -+ 8, -+ DECOMPRESS_BROKEN_TRUNCATED -+ }, -+ /* compressed chunk without backwards reference and unused bits != 0 */ -+ { -+ {0x01, 0xB0, 0x02, 'W'}, -+ 4, -+ STATUS_SUCCESS, -+ "W", -+ 1 -+ }, -+ /* termination sequence after first chunk */ -+ { -+ {0x03, 0x30, 'W', 'i', 'n', 'e', 0x00, 0x00, 0x03, 0x30, 'W', 'i', 'n', 'e'}, -+ 14, -+ STATUS_SUCCESS, -+ "Wine", -+ 4, -+ DECOMPRESS_BROKEN_FRAGMENT4095 | -+ DECOMPRESS_BROKEN_FRAGMENT1 | -+ DECOMPRESS_BROKEN_FRAGMENT0 -+ }, -+ /* compressed chunk using backwards reference with 4 bit offset, 12 bit length */ -+ { -+ {0x14, 0xB0, 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', -+ 0x00, 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', -+ 0x01, 0x01, 0xF0}, -+ 23, -+ STATUS_SUCCESS, -+ "ABCDEFGHIJKLMNOPABCD", -+ 20, -+ DECOMPRESS_BROKEN_TRUNCATED -+ }, -+ /* compressed chunk using backwards reference with 5 bit offset, 11 bit length */ -+ { -+ {0x15, 0xB0, 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', -+ 0x00, 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', -+ 0x02, 'A', 0x00, 0x78}, -+ 24, -+ STATUS_SUCCESS, -+ "ABCDEFGHIJKLMNOPABCD", -+ 20, -+ DECOMPRESS_BROKEN_TRUNCATED -+ }, -+ /* uncompressed chunk with invalid magic */ -+ { -+ {0x03, 0x20, 'W', 'i', 'n', 'e'}, -+ 6, -+ STATUS_SUCCESS, -+ "Wine", -+ 4, -+ DECOMPRESS_BROKEN_FRAGMENT4095 | -+ DECOMPRESS_BROKEN_FRAGMENT1 | -+ DECOMPRESS_BROKEN_FRAGMENT0 -+ }, -+ /* compressed chunk with invalid magic */ -+ { -+ {0x04, 0xA0, 0x00, 'W', 'i', 'n', 'e'}, -+ 7, -+ STATUS_SUCCESS, -+ "Wine", -+ 4 -+ }, -+ /* garbage byte after end of buffer */ -+ { -+ {0x00, 0xB0, 0x02, 0x01}, -+ 4, -+ STATUS_SUCCESS, -+ "", -+ 0 -+ }, -+ /* empty compressed chunk */ -+ { -+ {0x00, 0xB0, 0x00}, -+ 3, -+ STATUS_SUCCESS, -+ "", -+ 0 -+ }, -+ /* empty compressed chunk with unused bits != 0 */ -+ { -+ {0x00, 0xB0, 0x01}, -+ 3, -+ STATUS_SUCCESS, -+ "", -+ 0 -+ }, -+ /* empty input buffer */ -+ { -+ {}, -+ 0, -+ STATUS_BAD_COMPRESSION_BUFFER, -+ }, -+ /* incomplete chunk header */ -+ { -+ {0x01}, -+ 1, -+ STATUS_BAD_COMPRESSION_BUFFER -+ }, -+ /* incomplete chunk header */ -+ { -+ {0x00, 0x30}, -+ 2, -+ STATUS_BAD_COMPRESSION_BUFFER -+ }, -+ /* compressed chunk with invalid backwards reference */ -+ { -+ {0x06, 0xB0, 0x10, 'W', 'i', 'n', 'e', 0x05, 0x40}, -+ 9, -+ STATUS_BAD_COMPRESSION_BUFFER -+ }, -+ /* compressed chunk with incomplete backwards reference */ -+ { -+ {0x05, 0xB0, 0x10, 'W', 'i', 'n', 'e', 0x05}, -+ 8, -+ STATUS_BAD_COMPRESSION_BUFFER -+ }, -+ /* incomplete uncompressed chunk */ -+ { -+ {0x07, 0x30, 'W', 'i', 'n', 'e'}, -+ 6, -+ STATUS_BAD_COMPRESSION_BUFFER -+ }, -+ /* incomplete compressed chunk */ -+ { -+ {0x08, 0xB0, 0x00, 'W', 'i', 'n', 'e'}, -+ 7, -+ STATUS_BAD_COMPRESSION_BUFFER -+ }, -+ /* two compressed chunks, the second one incomplete */ -+ { -+ {0x00, 0xB0, 0x02, 0x00, 0xB0}, -+ 5, -+ STATUS_BAD_COMPRESSION_BUFFER, -+ } -+ }; -+ -+ static UCHAR buf[0x2000], workspace[0x1000]; -+ NTSTATUS status, expected_status; -+ ULONG final_size; -+ int i; -+ -+ if (!pRtlDecompressBuffer || !pRtlDecompressFragment) -+ { -+ win_skip("RtlDecompressBuffer or RtlDecompressFragment is not available\n"); -+ return; -+ } -+ -+ /* test compression format / engine */ -+ final_size = 0xdeadbeef; -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_NONE, buf, sizeof(buf) - 1, test_lznt[0].compressed, -+ test_lznt[0].compressed_size, &final_size); -+ ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08x\n", status); -+ ok(final_size == 0xdeadbeef, "got wrong final_size %d\n", final_size); -+ -+ final_size = 0xdeadbeef; -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_DEFAULT, buf, sizeof(buf) - 1, test_lznt[0].compressed, -+ test_lznt[0].compressed_size, &final_size); -+ ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08x\n", status); -+ ok(final_size == 0xdeadbeef, "got wrong final_size %d\n", final_size); -+ -+ final_size = 0xdeadbeef; -+ status = pRtlDecompressBuffer(0xFF, buf, sizeof(buf) - 1, test_lznt[0].compressed, -+ test_lznt[0].compressed_size, &final_size); -+ ok(status == STATUS_UNSUPPORTED_COMPRESSION, "got wrong status 0x%08x\n", status); -+ ok(final_size == 0xdeadbeef, "got wrong final_size %d\n", final_size); -+ -+ /* regular tests for RtlDecompressBuffer */ -+ for (i = 0; i < sizeof(test_lznt) / sizeof(test_lznt[0]); i++) -+ { -+ trace("Running test %d (compressed_size=%d, compressed_size=%d, status=%d)\n", -+ i, test_lznt[i].compressed_size, test_lznt[i].compressed_size, test_lznt[i].status); -+ -+ /* test with very big buffer */ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, -+ test_lznt[i].compressed_size, &final_size); -+ ok(status == test_lznt[i].status, "%d: got wrong status 0x%08x\n", i, status); -+ if (!status) -+ { -+ ok(final_size == test_lznt[i].uncompressed_size, -+ "%d: got wrong final_size %d\n", i, final_size); -+ ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size), -+ "%d: got wrong decoded data\n", i); -+ ok(buf[test_lznt[i].uncompressed_size] == 0x11, -+ "%d: buf[%d] overwritten\n", i, test_lznt[i].uncompressed_size); -+ } -+ -+ /* test that modifier for compression engine is ignored */ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM, buf, sizeof(buf), -+ test_lznt[i].compressed, test_lznt[i].compressed_size, &final_size); -+ ok(status == test_lznt[i].status, "%d: got wrong status 0x%08x\n", i, status); -+ if (!status) -+ { -+ ok(final_size == test_lznt[i].uncompressed_size, -+ "%d: got wrong final_size %d\n", i, final_size); -+ ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size), -+ "%d: got wrong decoded data\n", i); -+ ok(buf[test_lznt[i].uncompressed_size] == 0x11, -+ "%d: buf[%d] overwritten\n", i, test_lznt[i].uncompressed_size); -+ } -+ -+ /* test with expected output size */ -+ if (test_lznt[i].uncompressed_size > 0) -+ { -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, test_lznt[i].uncompressed_size, -+ test_lznt[i].compressed, test_lznt[i].compressed_size, &final_size); -+ ok(status == test_lznt[i].status, "%d: got wrong status 0x%08x\n", i, status); -+ if (!status) -+ { -+ ok(final_size == test_lznt[i].uncompressed_size, -+ "%d: got wrong final_size %d\n", i, final_size); -+ ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size), -+ "%d: got wrong decoded data\n", i); -+ ok(buf[test_lznt[i].uncompressed_size] == 0x11, -+ "%d: buf[%d] overwritten\n", i, test_lznt[i].uncompressed_size); -+ } -+ } -+ -+ /* test with smaller output size */ -+ if (test_lznt[i].uncompressed_size > 1) -+ { -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, test_lznt[i].uncompressed_size - 1, -+ test_lznt[i].compressed, test_lznt[i].compressed_size, &final_size); -+ ok(status == test_lznt[i].status || broken(status == STATUS_BAD_COMPRESSION_BUFFER && -+ (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_TRUNCATED)), "%d: got wrong status 0x%08x\n", i, status); -+ if (!status) -+ { -+ ok(final_size == test_lznt[i].uncompressed_size - 1, -+ "%d: got wrong final_size %d\n", i, final_size); -+ ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size - 1), -+ "%d: got wrong decoded data\n", i); -+ ok(buf[test_lznt[i].uncompressed_size - 1] == 0x11, -+ "%d: buf[%d] overwritten\n", i, test_lznt[i].uncompressed_size - 1); -+ } -+ } -+ -+ /* test with zero output size */ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, 0, test_lznt[i].compressed, -+ test_lznt[i].compressed_size, &final_size); -+ if (is_incomplete_chunk(test_lznt[i].compressed, test_lznt[i].compressed_size, FALSE)) -+ { -+ ok(status == STATUS_BAD_COMPRESSION_BUFFER, "%d: got wrong status 0x%08x\n", i, status); -+ } -+ else -+ { -+ ok(status == STATUS_SUCCESS, "%d: got wrong status 0x%08x\n", i, status); -+ ok(final_size == 0, "%d: got wrong final_size %d\n", i, final_size); -+ ok(buf[0] == 0x11, "%d: buf[%d] overwritten\n", i, test_lznt[i].uncompressed_size); -+ } -+ -+ /* test RtlDecompressBuffer with offset = 0 */ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, -+ test_lznt[i].compressed_size, 0, &final_size, workspace); -+ ok(status == test_lznt[i].status || broken(status == STATUS_BAD_COMPRESSION_BUFFER && -+ (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT0)), "%d: got wrong status 0x%08x\n", i, status); -+ if (!status) -+ { -+ ok(final_size == test_lznt[i].uncompressed_size, -+ "%d: got wrong final_size %d\n", i, final_size); -+ ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size), -+ "%d: got wrong decoded data\n", i); -+ ok(buf[test_lznt[i].uncompressed_size] == 0x11, -+ "%d: buf[%d] overwritten\n", i, test_lznt[i].uncompressed_size); -+ } -+ -+ /* test RtlDecompressBuffer with offset = 1 */ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, -+ test_lznt[i].compressed_size, 1, &final_size, workspace); -+ ok(status == test_lznt[i].status || broken(status == STATUS_BAD_COMPRESSION_BUFFER && -+ (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT1)), "%d: got wrong status 0x%08x\n", i, status); -+ if (!status) -+ { -+ if (test_lznt[i].uncompressed_size == 0) -+ { -+ todo_wine -+ ok(final_size == 4095, -+ "%d: got wrong final size %d\n", i, final_size); -+ /* Buffer doesn't contain any useful value on Windows */ -+ ok(buf[4095] == 0x11, -+ "%d: buf[4095] overwritten\n", i); -+ } -+ else -+ { -+ ok(final_size == test_lznt[i].uncompressed_size - 1, -+ "%d: got wrong final_size %d\n", i, final_size); -+ ok(!memcmp(buf, test_lznt[i].uncompressed + 1, test_lznt[i].uncompressed_size - 1), -+ "%d: got wrong decoded data\n", i); -+ ok(buf[test_lznt[i].uncompressed_size - 1] == 0x11, -+ "%d: buf[%d] overwritten\n", i, test_lznt[i].uncompressed_size - 1); -+ } -+ } -+ -+ /* test RtlDecompressBuffer with offset = 4095 */ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, -+ test_lznt[i].compressed_size, 4095, &final_size, workspace); -+ ok(status == test_lznt[i].status || broken(status == STATUS_BAD_COMPRESSION_BUFFER && -+ (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT4095)), "%d: got wrong status 0x%08x\n", i, status); -+ if (!status) -+ { -+ todo_wine -+ ok(final_size == 1, -+ "%d: got wrong final size %d\n", i, final_size); -+ todo_wine -+ ok(buf[0] == 0, -+ "%d: padding is not zero\n", i); -+ ok(buf[1] == 0x11, -+ "%d: buf[1] overwritten\n", i); -+ } -+ -+ /* test RtlDecompressBuffer with offset = 4096 */ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, -+ test_lznt[i].compressed_size, 4096, &final_size, workspace); -+ expected_status = is_incomplete_chunk(test_lznt[i].compressed, test_lznt[i].compressed_size, TRUE) ? -+ test_lznt[i].status : STATUS_SUCCESS; -+ ok(status == expected_status, "%d: got wrong status 0x%08x, expected 0x%08x\n", i, status, expected_status); -+ if (!status) -+ { -+ ok(final_size == 0, -+ "%d: got wrong final size %d\n", i, final_size); -+ ok(buf[0] == 0x11, -+ "%d: buf[4096] overwritten\n", i); -+ } -+ } -+ -+ /* test decoding of multiple chunks with pRtlDecompressBuffer */ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_multiple_chunks, -+ sizeof(test_multiple_chunks), &final_size); -+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 4100, "got wrong final_size %d\n", final_size); -+ ok(!memcmp(buf, "Wine", 4), "got wrong decoded data at offset 0\n"); -+ ok(buf[4] == 0 && buf[4095] == 0, "padding is not zero\n"); -+ ok(!memcmp(buf + 4096, "Wine", 4), "got wrong decoded data at offset 4096\n"); -+ ok(buf[4100] == 0x11, "buf[4100] overwritten\n"); -+ } -+ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, 4097, test_multiple_chunks, -+ sizeof(test_multiple_chunks), &final_size); -+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 4097, "got wrong final_size %d\n", final_size); -+ ok(!memcmp(buf, "Wine", 4), "got wrong decoded data at offset 0\n"); -+ ok(buf[4] == 0 && buf[4095] == 0, "padding is not zero\n"); -+ ok(buf[4096], "got wrong decoded data at offset 4096\n"); -+ ok(buf[4097] == 0x11, "buf[4097] overwritten\n"); -+ } -+ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, 4096, test_multiple_chunks, -+ sizeof(test_multiple_chunks), &final_size); -+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 4, "got wrong final_size %d\n", final_size); -+ ok(!memcmp(buf, "Wine", 4), "got wrong decoded data at offset 0\n"); -+ ok(buf[4] == 0x11, "buf[4] overwritten\n"); -+ } -+ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, 4, test_multiple_chunks, -+ sizeof(test_multiple_chunks), &final_size); -+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 4, "got wrong final_size %d\n", final_size); -+ ok(!memcmp(buf, "Wine", 4), "got wrong decoded data at offset 0\n"); -+ ok(buf[4] == 0x11, "buf[4] overwritten\n"); -+ } -+ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, 3, test_multiple_chunks, -+ sizeof(test_multiple_chunks), &final_size); -+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 3, "got wrong final_size %d\n", final_size); -+ ok(!memcmp(buf, "Wine", 3), "got wrong decoded data at offset 0\n"); -+ ok(buf[3] == 0x11, "buf[3] overwritten\n"); -+ } -+ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, 0, test_multiple_chunks, -+ sizeof(test_multiple_chunks), &final_size); -+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 0, "got wrong final_size %d\n", final_size); -+ ok(buf[0] == 0x11, "buf[0] overwritten\n"); -+ } -+ -+ /* test multiple chunks in combination with RtlDecompressBuffer and offset=1 */ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_multiple_chunks, -+ sizeof(test_multiple_chunks), 1, &final_size, workspace); -+ ok(status == STATUS_SUCCESS || broken(status == STATUS_BAD_COMPRESSION_BUFFER), -+ "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 4099, "got wrong final_size %d\n", final_size); -+ ok(!memcmp(buf, "ine", 3), "got wrong decoded data at offset 0\n"); -+ ok(buf[3] == 0 && buf[4094] == 0, "padding is not zero\n"); -+ ok(!memcmp(buf + 4095, "Wine", 4), "got wrong decoded data at offset 4095\n"); -+ ok(buf[4099] == 0x11, "buf[4099] overwritten\n"); -+ } -+ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, 4096, test_multiple_chunks, -+ sizeof(test_multiple_chunks), 1, &final_size, workspace); -+ ok(status == STATUS_SUCCESS || broken(status == STATUS_BAD_COMPRESSION_BUFFER), -+ "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 4096, "got wrong final_size %d\n", final_size); -+ ok(!memcmp(buf, "ine", 3), "got wrong decoded data at offset 0\n"); -+ ok(buf[3] == 0 && buf[4094] == 0, "padding is not zero\n"); -+ ok(buf[4095] == 'W', "got wrong decoded data at offset 4095\n"); -+ ok(buf[4096] == 0x11, "buf[4096] overwritten\n"); -+ } -+ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, 4095, test_multiple_chunks, -+ sizeof(test_multiple_chunks), 1, &final_size, workspace); -+ ok(status == STATUS_SUCCESS || broken(status == STATUS_BAD_COMPRESSION_BUFFER), -+ "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 3, "got wrong final_size %d\n", final_size); -+ ok(!memcmp(buf, "ine", 3), "got wrong decoded data at offset 0\n"); -+ ok(buf[4] == 0x11, "buf[4] overwritten\n"); -+ } -+ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, 3, test_multiple_chunks, -+ sizeof(test_multiple_chunks), 1, &final_size, workspace); -+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 3, "got wrong final_size %d\n", final_size); -+ ok(!memcmp(buf, "ine", 3), "got wrong decoded data at offset 0\n"); -+ ok(buf[3] == 0x11, "buf[3] overwritten\n"); -+ } -+ -+ /* test multiple chunks in combination with RtlDecompressBuffer and offset=4 */ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_multiple_chunks, -+ sizeof(test_multiple_chunks), 4, &final_size, workspace); -+ ok(status == STATUS_SUCCESS || broken(status == STATUS_BAD_COMPRESSION_BUFFER), -+ "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 4096, "got wrong final_size %d\n", final_size); -+ ok(buf[0] == 0 && buf[4091] == 0, "padding is not zero\n"); -+ ok(!memcmp(buf + 4092, "Wine", 4), "got wrong decoded data at offset 4092\n"); -+ ok(buf[4096] == 0x11, "buf[4096] overwritten\n"); -+ } -+ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_multiple_chunks, -+ sizeof(test_multiple_chunks), 4095, &final_size, workspace); -+ ok(status == STATUS_SUCCESS || broken(status == STATUS_BAD_COMPRESSION_BUFFER), -+ "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 5, "got wrong final_size %d\n", final_size); -+ ok(buf[0] == 0, "padding is not zero\n"); -+ ok(!memcmp(buf + 1, "Wine", 4), "got wrong decoded data at offset 1\n"); -+ ok(buf[5] == 0x11, "buf[5] overwritten\n"); -+ } -+ -+ final_size = 0xdeadbeef; -+ memset(buf, 0x11, sizeof(buf)); -+ status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_multiple_chunks, -+ sizeof(test_multiple_chunks), 4096, &final_size, workspace); -+ ok(status == STATUS_SUCCESS || broken(status == STATUS_BAD_COMPRESSION_BUFFER), -+ "got wrong status 0x%08x\n", status); -+ if (!status) -+ { -+ ok(final_size == 4, "got wrong final_size %d\n", final_size); -+ ok(!memcmp(buf, "Wine", 4), "got wrong decoded data at offset 0\n"); -+ ok(buf[4] == 0x11, "buf[4] overwritten\n"); -+ } -+ -+} -+ -+static void test_RtlCompressBuffer(void) -+{ -+ ULONG compress_workspace, decompress_workspace; -+ static const UCHAR test_buffer[] = "WineWineWine"; -+ static UCHAR buf1[0x1000], buf2[0x1000], *workspace; -+ ULONG final_size, buf_size; -+ NTSTATUS status; -+ -+ if (!pRtlCompressBuffer || !pRtlGetCompressionWorkSpaceSize) -+ { -+ win_skip("RtlCompressBuffer or RtlGetCompressionWorkSpaceSize is not available\n"); -+ return; -+ } -+ -+ compress_workspace = decompress_workspace = 0xdeadbeef; -+ status = pRtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_LZNT1, &compress_workspace, -+ &decompress_workspace); -+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ ok(compress_workspace != 0, "got wrong compress_workspace %d\n", compress_workspace); -+ -+ workspace = HeapAlloc( GetProcessHeap(), 0, compress_workspace ); -+ ok(workspace != NULL, "HeapAlloc failed %x\n", GetLastError()); -+ -+ /* test compression format / engine */ -+ final_size = 0xdeadbeef; -+ status = pRtlCompressBuffer(COMPRESSION_FORMAT_NONE, test_buffer, sizeof(test_buffer), -+ buf1, sizeof(buf1) - 1, 4096, &final_size, workspace); -+ ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08x\n", status); -+ ok(final_size == 0xdeadbeef, "got wrong final_size %d\n", final_size); -+ -+ final_size = 0xdeadbeef; -+ status = pRtlCompressBuffer(COMPRESSION_FORMAT_DEFAULT, test_buffer, sizeof(test_buffer), -+ buf1, sizeof(buf1) - 1, 4096, &final_size, workspace); -+ ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08x\n", status); -+ ok(final_size == 0xdeadbeef, "got wrong final_size %d\n", final_size); -+ -+ final_size = 0xdeadbeef; -+ status = pRtlCompressBuffer(0xFF, test_buffer, sizeof(test_buffer), -+ buf1, sizeof(buf1) - 1, 4096, &final_size, workspace); -+ ok(status == STATUS_UNSUPPORTED_COMPRESSION, "got wrong status 0x%08x\n", status); -+ ok(final_size == 0xdeadbeef, "got wrong final_size %d\n", final_size); -+ -+ /* test compression */ -+ final_size = 0xdeadbeef; -+ memset(buf1, 0x11, sizeof(buf1)); -+ status = pRtlCompressBuffer(COMPRESSION_FORMAT_LZNT1, test_buffer, sizeof(test_buffer), -+ buf1, sizeof(buf1), 4096, &final_size, workspace); -+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ ok((*(WORD *)buf1 & 0x7000) == 0x3000, "no chunk signature found %04x\n", *(WORD *)buf1); -+ buf_size = final_size; -+ todo_wine -+ ok(final_size < sizeof(test_buffer), "got wrong final_size %d\n", final_size); -+ -+ /* test decompression */ -+ final_size = 0xdeadbeef; -+ memset(buf2, 0x11, sizeof(buf2)); -+ status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf2, sizeof(buf2), -+ buf1, buf_size, &final_size); -+ ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ ok(final_size == sizeof(test_buffer), "got wrong final_size %d\n", final_size); -+ ok(!memcmp(buf2, test_buffer, sizeof(test_buffer)), "got wrong decoded data\n"); -+ ok(buf2[sizeof(test_buffer)] == 0x11, "buf[%u] overwritten\n", (DWORD)sizeof(test_buffer)); -+ -+ /* buffer too small */ -+ final_size = 0xdeadbeef; -+ memset(buf1, 0x11, sizeof(buf1)); -+ status = pRtlCompressBuffer(COMPRESSION_FORMAT_LZNT1, test_buffer, sizeof(test_buffer), -+ buf1, 4, 4096, &final_size, workspace); -+ ok(status == STATUS_BUFFER_TOO_SMALL, "got wrong status 0x%08x\n", status); -+ -+ HeapFree(GetProcessHeap(), 0, workspace); -+} -+ - START_TEST(rtl) - { - InitFunctionPtrs(); -@@ -1625,4 +2362,7 @@ START_TEST(rtl) - test_RtlIpv4StringToAddress(); - test_LdrAddRefDll(); - test_LdrLockLoaderLock(); -+ test_RtlGetCompressionWorkSpaceSize(); -+ test_RtlDecompressBuffer(); -+ test_RtlCompressBuffer(); - } --- -2.3.1 - diff --git a/patches/ntdll-LZNT1_Compression/0005-ntdll-tests-Fix-various-test-failures-caused-by-brok.patch b/patches/ntdll-LZNT1_Compression/0005-ntdll-tests-Fix-various-test-failures-caused-by-brok.patch deleted file mode 100644 index e12d73b8..00000000 --- a/patches/ntdll-LZNT1_Compression/0005-ntdll-tests-Fix-various-test-failures-caused-by-brok.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 8a8496e747ef2dff43763a3d3dfd7f1d68160adc Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Tue, 10 Mar 2015 20:09:59 +0100 -Subject: ntdll/tests: Fix various test failures caused by broken - RtlDecompressBuffer results. - ---- - dlls/ntdll/tests/rtl.c | 41 ++++++++++++++++++----------------------- - 1 file changed, 18 insertions(+), 23 deletions(-) - -diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c -index 2f6c421..843e8e7 100644 ---- a/dlls/ntdll/tests/rtl.c -+++ b/dlls/ntdll/tests/rtl.c -@@ -1664,9 +1664,7 @@ static BOOL is_incomplete_chunk(const UCHAR *compressed, ULONG compressed_size, - } - - #define DECOMPRESS_BROKEN_TRUNCATED 1 --#define DECOMPRESS_BROKEN_FRAGMENT0 2 --#define DECOMPRESS_BROKEN_FRAGMENT1 4 --#define DECOMPRESS_BROKEN_FRAGMENT4095 8 -+#define DECOMPRESS_BROKEN_FRAGMENT 2 - - static void test_RtlDecompressBuffer(void) - { -@@ -1690,9 +1688,7 @@ static void test_RtlDecompressBuffer(void) - STATUS_SUCCESS, - "Wine", - 4, -- DECOMPRESS_BROKEN_FRAGMENT4095 | -- DECOMPRESS_BROKEN_FRAGMENT1 | -- DECOMPRESS_BROKEN_FRAGMENT0 -+ DECOMPRESS_BROKEN_FRAGMENT - }, - /* 8 byte uncompressed chunk */ - { -@@ -1701,9 +1697,7 @@ static void test_RtlDecompressBuffer(void) - STATUS_SUCCESS, - "WineWine", - 8, -- DECOMPRESS_BROKEN_FRAGMENT4095 | -- DECOMPRESS_BROKEN_FRAGMENT1 | -- DECOMPRESS_BROKEN_FRAGMENT0 -+ DECOMPRESS_BROKEN_FRAGMENT - }, - /* 4 byte compressed chunk */ - { -@@ -1763,9 +1757,7 @@ static void test_RtlDecompressBuffer(void) - STATUS_SUCCESS, - "Wine", - 4, -- DECOMPRESS_BROKEN_FRAGMENT4095 | -- DECOMPRESS_BROKEN_FRAGMENT1 | -- DECOMPRESS_BROKEN_FRAGMENT0 -+ DECOMPRESS_BROKEN_FRAGMENT - }, - /* compressed chunk using backwards reference with 4 bit offset, 12 bit length */ - { -@@ -1796,9 +1788,7 @@ static void test_RtlDecompressBuffer(void) - STATUS_SUCCESS, - "Wine", - 4, -- DECOMPRESS_BROKEN_FRAGMENT4095 | -- DECOMPRESS_BROKEN_FRAGMENT1 | -- DECOMPRESS_BROKEN_FRAGMENT0 -+ DECOMPRESS_BROKEN_FRAGMENT - }, - /* compressed chunk with invalid magic */ - { -@@ -1923,7 +1913,8 @@ static void test_RtlDecompressBuffer(void) - memset(buf, 0x11, sizeof(buf)); - status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, - test_lznt[i].compressed_size, &final_size); -- ok(status == test_lznt[i].status, "%d: got wrong status 0x%08x\n", i, status); -+ ok(status == test_lznt[i].status || broken(status == STATUS_BAD_COMPRESSION_BUFFER && -+ (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT)), "%d: got wrong status 0x%08x\n", i, status); - if (!status) - { - ok(final_size == test_lznt[i].uncompressed_size, -@@ -1939,7 +1930,8 @@ static void test_RtlDecompressBuffer(void) - memset(buf, 0x11, sizeof(buf)); - status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM, buf, sizeof(buf), - test_lznt[i].compressed, test_lznt[i].compressed_size, &final_size); -- ok(status == test_lznt[i].status, "%d: got wrong status 0x%08x\n", i, status); -+ ok(status == test_lznt[i].status || broken(status == STATUS_BAD_COMPRESSION_BUFFER && -+ (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT)), "%d: got wrong status 0x%08x\n", i, status); - if (!status) - { - ok(final_size == test_lznt[i].uncompressed_size, -@@ -2011,7 +2003,7 @@ static void test_RtlDecompressBuffer(void) - status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, - test_lznt[i].compressed_size, 0, &final_size, workspace); - ok(status == test_lznt[i].status || broken(status == STATUS_BAD_COMPRESSION_BUFFER && -- (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT0)), "%d: got wrong status 0x%08x\n", i, status); -+ (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT)), "%d: got wrong status 0x%08x\n", i, status); - if (!status) - { - ok(final_size == test_lznt[i].uncompressed_size, -@@ -2028,7 +2020,7 @@ static void test_RtlDecompressBuffer(void) - status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, - test_lznt[i].compressed_size, 1, &final_size, workspace); - ok(status == test_lznt[i].status || broken(status == STATUS_BAD_COMPRESSION_BUFFER && -- (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT1)), "%d: got wrong status 0x%08x\n", i, status); -+ (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT)), "%d: got wrong status 0x%08x\n", i, status); - if (!status) - { - if (test_lznt[i].uncompressed_size == 0) -@@ -2057,7 +2049,7 @@ static void test_RtlDecompressBuffer(void) - status = pRtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed, - test_lznt[i].compressed_size, 4095, &final_size, workspace); - ok(status == test_lznt[i].status || broken(status == STATUS_BAD_COMPRESSION_BUFFER && -- (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT4095)), "%d: got wrong status 0x%08x\n", i, status); -+ (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT)), "%d: got wrong status 0x%08x\n", i, status); - if (!status) - { - todo_wine -@@ -2092,7 +2084,8 @@ static void test_RtlDecompressBuffer(void) - memset(buf, 0x11, sizeof(buf)); - status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_multiple_chunks, - sizeof(test_multiple_chunks), &final_size); -- ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ ok(status == STATUS_SUCCESS || broken(status == STATUS_BAD_COMPRESSION_BUFFER), -+ "got wrong status 0x%08x\n", status); - if (!status) - { - ok(final_size == 4100, "got wrong final_size %d\n", final_size); -@@ -2106,7 +2099,8 @@ static void test_RtlDecompressBuffer(void) - memset(buf, 0x11, sizeof(buf)); - status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, 4097, test_multiple_chunks, - sizeof(test_multiple_chunks), &final_size); -- ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ ok(status == STATUS_SUCCESS || broken(status == STATUS_BAD_COMPRESSION_BUFFER), -+ "got wrong status 0x%08x\n", status); - if (!status) - { - ok(final_size == 4097, "got wrong final_size %d\n", final_size); -@@ -2120,7 +2114,8 @@ static void test_RtlDecompressBuffer(void) - memset(buf, 0x11, sizeof(buf)); - status = pRtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, 4096, test_multiple_chunks, - sizeof(test_multiple_chunks), &final_size); -- ok(status == STATUS_SUCCESS, "got wrong status 0x%08x\n", status); -+ ok(status == STATUS_SUCCESS || broken(status == STATUS_BAD_COMPRESSION_BUFFER), -+ "got wrong status 0x%08x\n", status); - if (!status) - { - ok(final_size == 4, "got wrong final_size %d\n", final_size); --- -2.3.1 - diff --git a/patches/ntdll-RtlIpStringToAddress/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch b/patches/ntdll-RtlIpStringToAddress/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch index 0f99b424..2fc135f8 100644 --- a/patches/ntdll-RtlIpStringToAddress/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch +++ b/patches/ntdll-RtlIpStringToAddress/0001-ntdll-tests-Tests-for-RtlIpv6StringToAddress-try-6.patch @@ -1,4 +1,4 @@ -From 0200b5ccf86d7b87846f4d8c98f9ac0775e810d8 Mon Sep 17 00:00:00 2001 +From 14cab3188b8f83081a686892d94594a30abebf14 Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Sun, 8 Mar 2015 18:24:45 +0100 Subject: ntdll/tests: Tests for RtlIpv6StringToAddress (try 6) @@ -22,7 +22,7 @@ duplication 1 file changed, 430 insertions(+) diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c -index 2f6c421..d4c83c2 100644 +index 4903790..47acfe9 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -25,6 +25,7 @@ @@ -488,14 +488,14 @@ index 2f6c421..d4c83c2 100644 static void test_LdrAddRefDll(void) { HMODULE mod, mod2; -@@ -2360,6 +2789,7 @@ START_TEST(rtl) +@@ -2186,6 +2615,7 @@ START_TEST(rtl) test_RtlIpv4AddressToString(); test_RtlIpv4AddressToStringEx(); test_RtlIpv4StringToAddress(); + test_RtlIpv6StringToAddress(); test_LdrAddRefDll(); test_LdrLockLoaderLock(); - test_RtlGetCompressionWorkSpaceSize(); + test_RtlCompressBuffer(); -- -2.3.1 +2.4.5 diff --git a/patches/ntdll-RtlIpStringToAddress/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch b/patches/ntdll-RtlIpStringToAddress/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch index d5af9056..ddfac3c9 100644 --- a/patches/ntdll-RtlIpStringToAddress/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch +++ b/patches/ntdll-RtlIpStringToAddress/0002-ntdll-tests-Tests-for-RtlIpv6StringToAddressEx-try-6.patch @@ -1,4 +1,4 @@ -From 486707397ce18ce3f92f0ffbc388626312d9f952 Mon Sep 17 00:00:00 2001 +From 7b6d523f37901554bfdb17e301dd25e50a899e22 Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Sun, 8 Mar 2015 18:24:50 +0100 Subject: ntdll/tests: Tests for RtlIpv6StringToAddressEx (try 6) @@ -21,7 +21,7 @@ Changes from try3: 1 file changed, 268 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c -index d4c83c2..b389d6f 100644 +index 47acfe9..f5bbbb3 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -92,6 +92,8 @@ static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, L @@ -320,14 +320,14 @@ index d4c83c2..b389d6f 100644 static void test_LdrAddRefDll(void) { HMODULE mod, mod2; -@@ -2790,6 +3056,7 @@ START_TEST(rtl) +@@ -2616,6 +2882,7 @@ START_TEST(rtl) test_RtlIpv4AddressToStringEx(); test_RtlIpv4StringToAddress(); test_RtlIpv6StringToAddress(); + test_RtlIpv6StringToAddressEx(); test_LdrAddRefDll(); test_LdrLockLoaderLock(); - test_RtlGetCompressionWorkSpaceSize(); + test_RtlCompressBuffer(); -- -2.3.1 +2.4.5 diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 4dd8c19e..8a940508 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -55,7 +55,7 @@ version() echo "Copyright (C) 2014-2015 the Wine Staging project authors." echo "" echo "Patchset to be applied on upstream Wine:" - echo " commit 47a11ec626dc8888442ab0f5eb943e1d33048114" + echo " commit cf7a118a9e5922d819f216c21c3a0984c7bde5dd" echo "" } @@ -3547,20 +3547,16 @@ fi # | * [#37449] Support for RtlDecompressBuffer # | # | Modified files: -# | * dlls/ntdll/ntdll.spec, dlls/ntdll/rtl.c, dlls/ntdll/tests/rtl.c, dlls/ntoskrnl.exe/ntoskrnl.exe.spec, include/winnt.h +# | * dlls/ntdll/ntdll.spec, dlls/ntdll/rtl.c, dlls/ntdll/tests/rtl.c, dlls/ntoskrnl.exe/ntoskrnl.exe.spec # | if test "$enable_ntdll_LZNT1_Compression" -eq 1; then - patch_apply ntdll-LZNT1_Compression/0001-ntdll-Implement-semi-stub-for-RtlGetCompressionWorkS.patch - patch_apply ntdll-LZNT1_Compression/0002-ntdll-Implement-semi-stub-for-RtlCompressBuffer.patch - patch_apply ntdll-LZNT1_Compression/0003-ntdll-Implement-LZNT1-algorithm-for-RtlDecompressBuf.patch - patch_apply ntdll-LZNT1_Compression/0004-ntdll-tests-Add-tests-for-Rtl-Decompress-Compress-Bu.patch - patch_apply ntdll-LZNT1_Compression/0005-ntdll-tests-Fix-various-test-failures-caused-by-brok.patch + patch_apply ntdll-LZNT1_Compression/0001-ntdll-Implement-RtlDecompressFragment.patch + patch_apply ntdll-LZNT1_Compression/0002-ntdll-tests-Add-tests-for-RtlDecompressBuffer.patch + patch_apply ntdll-LZNT1_Compression/0003-ntdll-tests-Add-tests-for-RtlDecompressFragment.patch ( - echo '+ { "Sebastian Lackner", "ntdll: Implement semi-stub for RtlGetCompressionWorkSpaceSize.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll: Implement semi-stub for RtlCompressBuffer.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll: Implement LZNT1 algorithm for RtlDecompressBuffer.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll/tests: Add tests for Rtl[Decompress|Compress]Buffer and RtlGetCompressionWorkSpaceSize.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll/tests: Fix various test failures caused by broken RtlDecompressBuffer results.", 1 },'; + echo '+ { "Sebastian Lackner", "ntdll: Implement RtlDecompressFragment.", 1 },'; + echo '+ { "Sebastian Lackner", "ntdll/tests: Add tests for RtlDecompressBuffer.", 1 },'; + echo '+ { "Sebastian Lackner", "ntdll/tests: Add tests for RtlDecompressFragment.", 1 },'; ) >> "$patchlist" fi diff --git a/patches/wined3d-CSMT_Main/9999-IfDefined.patch b/patches/wined3d-CSMT_Main/9999-IfDefined.patch index 0a7c6e25..f634c197 100644 --- a/patches/wined3d-CSMT_Main/9999-IfDefined.patch +++ b/patches/wined3d-CSMT_Main/9999-IfDefined.patch @@ -1155,7 +1155,7 @@ diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c -@@ -85,8 +85,10 @@ +@@ -86,8 +86,10 @@ ~0U, /* No GS shader model limit by default. */ ~0U, /* No PS shader model limit by default. */ FALSE, /* 3D support enabled by default. */ @@ -1166,7 +1166,7 @@ diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c }; struct wined3d * CDECL wined3d_create(DWORD flags) -@@ -306,6 +308,7 @@ +@@ -316,6 +318,7 @@ TRACE("Disabling 3D support.\n"); wined3d_settings.no_3d = TRUE; } @@ -1174,7 +1174,7 @@ diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c if (!get_config_key(hkey, appkey, "CSMT", buffer, size) && !strcmp(buffer,"disabled")) { -@@ -322,6 +325,9 @@ +@@ -332,6 +335,9 @@ FIXME_(winediag)("Experimental wined3d CSMT feature is currently %s.\n", wined3d_settings.cs_multithreaded ? "enabled" : "disabled"); @@ -1291,7 +1291,7 @@ diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c -@@ -1475,6 +1475,7 @@ +@@ -1509,6 +1509,7 @@ goto out; } @@ -1299,7 +1299,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c ret->current_fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret->current_fb.render_targets) * gl_info->limits.buffers); ret->current_fb.rt_size = gl_info->limits.buffers; -@@ -1483,6 +1484,7 @@ +@@ -1517,6 +1518,7 @@ if (device->context_count) ret->offscreenBuffer = device->contexts[0]->offscreenBuffer; @@ -1307,7 +1307,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c /* Initialize the texture unit mapping to a 1:1 mapping */ for (s = 0; s < MAX_COMBINED_SAMPLERS; ++s) { -@@ -1801,7 +1803,9 @@ +@@ -1821,7 +1823,9 @@ out: device->shader_backend->shader_free_context_data(ret); device->adapter->fragment_pipe->free_context_data(ret); @@ -1317,7 +1317,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c HeapFree(GetProcessHeap(), 0, ret->free_event_queries); HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries); HeapFree(GetProcessHeap(), 0, ret->free_timestamp_queries); -@@ -1836,7 +1840,9 @@ +@@ -1856,7 +1860,9 @@ device->shader_backend->shader_free_context_data(context); device->adapter->fragment_pipe->free_context_data(context); @@ -1327,7 +1327,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c HeapFree(GetProcessHeap(), 0, context->draw_buffers); HeapFree(GetProcessHeap(), 0, context->blit_targets); device_context_remove(device, context); -@@ -2244,7 +2250,11 @@ +@@ -2264,7 +2270,11 @@ return TRUE; } @@ -1339,7 +1339,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c static void context_validate_onscreen_formats(struct wined3d_context *context, const struct wined3d_rendertarget_view *depth_stencil) { -@@ -2260,6 +2270,7 @@ +@@ -2280,6 +2290,7 @@ WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n"); /* The currently active context is the necessary context to access the swapchain's onscreen buffers */ @@ -1347,7 +1347,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c wined3d_resource_load_location(&context->current_rt->resource, context, WINED3D_LOCATION_TEXTURE_RGB); swapchain->render_to_fbo = TRUE; swapchain_update_draw_bindings(swapchain); -@@ -2274,6 +2285,22 @@ +@@ -2294,6 +2305,22 @@ return context_generate_rt_mask_from_surface(rt); else return context_generate_rt_mask(context->offscreenBuffer); @@ -1370,7 +1370,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c } /* Context activation is done by the caller. */ -@@ -2305,7 +2332,11 @@ +@@ -2325,7 +2352,11 @@ } else { @@ -1382,7 +1382,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c } cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask; -@@ -2352,7 +2383,11 @@ +@@ -2372,7 +2403,11 @@ DWORD rt_mask = 0, *cur_mask; UINT i; @@ -1394,7 +1394,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c || rt_count != context->gl_info->limits.buffers) { if (!context_validate_rt_config(rt_count, rts, dsv)) -@@ -2394,11 +2429,17 @@ +@@ -2414,11 +2449,17 @@ } else { @@ -1412,7 +1412,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c } else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && (!rt_count || wined3d_resource_is_offscreen(rts[0]->resource))) -@@ -2411,7 +2452,11 @@ +@@ -2431,7 +2472,11 @@ } else { @@ -1424,7 +1424,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c rt_count ? wined3d_rendertarget_view_get_surface(rts[0]) : NULL); } -@@ -2446,6 +2491,7 @@ +@@ -2466,6 +2511,7 @@ return TRUE; } @@ -1432,7 +1432,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_state *state) { struct wined3d_rendertarget_view **rts = state->fb.render_targets; -@@ -2455,6 +2501,18 @@ +@@ -2475,6 +2521,18 @@ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return context_generate_rt_mask_no_fbo(context, wined3d_rendertarget_view_get_surface(rts[0])); @@ -1451,7 +1451,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c else if (!context->render_offscreen) return context_generate_rt_mask_from_surface(wined3d_rendertarget_view_get_surface(rts[0])); -@@ -2477,8 +2535,14 @@ +@@ -2497,8 +2555,14 @@ /* Context activation is done by the caller. */ void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { @@ -1466,7 +1466,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c DWORD *cur_mask; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) -@@ -2509,8 +2573,10 @@ +@@ -2529,8 +2593,10 @@ context_apply_draw_buffers(context, rt_mask); *cur_mask = rt_mask; } @@ -1477,7 +1477,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c } static void context_map_stage(struct wined3d_context *context, DWORD stage, DWORD unit) -@@ -2748,12 +2814,22 @@ +@@ -2768,12 +2834,22 @@ /* Context activation is done by the caller. */ void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { @@ -1500,7 +1500,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c if (rt_mask != *cur_mask) { context_apply_draw_buffers(context, rt_mask); -@@ -2955,7 +3031,11 @@ +@@ -2975,7 +3051,11 @@ { if (state->vertex_declaration->half_float_conv_needed && !stream_info->all_vbo) { @@ -1512,7 +1512,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c context->use_immediate_mode_draw = TRUE; } else -@@ -3095,11 +3175,19 @@ +@@ -3115,11 +3195,19 @@ } /* Context activation is done by the caller. */ @@ -1532,7 +1532,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c unsigned int i, j; WORD map; -@@ -3131,12 +3219,17 @@ +@@ -3151,12 +3239,17 @@ for (i = 0, map = context->stream_info.use_map; map; map >>= 1, ++i) { if (map & 1) @@ -1550,7 +1550,7 @@ diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c } if (state->index_buffer) { -@@ -3240,7 +3333,11 @@ +@@ -3260,7 +3353,11 @@ if (texture->texture_srgb.name) wined3d_texture_load(texture, context, TRUE); wined3d_texture_load(texture, context, FALSE); @@ -1747,7 +1747,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h #include #include #include -@@ -280,8 +308,10 @@ +@@ -278,8 +306,10 @@ unsigned int max_sm_gs; unsigned int max_sm_ps; BOOL no_3d; @@ -1758,7 +1758,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h }; extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN; -@@ -1014,9 +1044,14 @@ +@@ -1012,9 +1042,14 @@ WORD use_map; /* MAX_ATTRIBS, 16 */ }; @@ -1773,7 +1773,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; #define eps 1e-8f -@@ -1104,8 +1139,10 @@ +@@ -1102,8 +1137,10 @@ struct list entry; GLuint id; struct wined3d_context *context; @@ -1784,7 +1784,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h }; union wined3d_gl_query_object -@@ -1141,6 +1178,7 @@ +@@ -1139,6 +1176,7 @@ struct list entry; GLuint id; struct wined3d_context *context; @@ -1792,7 +1792,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h UINT64 timestamp; }; -@@ -1176,6 +1214,12 @@ +@@ -1174,6 +1212,12 @@ for (i = 0; i < min(dst->rt_size, src->rt_size); i++) dst->render_targets[i] = src->render_targets[i]; } @@ -1805,7 +1805,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h struct wined3d_context { -@@ -1191,7 +1235,9 @@ +@@ -1189,7 +1233,9 @@ DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */ DWORD numDirtyEntries; DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */ @@ -1815,7 +1815,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h struct wined3d_swapchain *swapchain; struct wined3d_surface *current_rt; -@@ -1291,8 +1337,17 @@ +@@ -1289,8 +1335,17 @@ GLfloat fog_coord_value; GLfloat color[4], fogstart, fogend, fogcolor[4]; GLuint dummy_arbfp_prog; @@ -1833,7 +1833,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h }; typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id); -@@ -1427,8 +1482,12 @@ +@@ -1425,8 +1480,12 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN; BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_device *device, UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN; @@ -1846,7 +1846,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target, struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN; void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, -@@ -1984,7 +2043,11 @@ +@@ -1983,7 +2042,11 @@ struct wined3d_state { DWORD flags; @@ -1858,7 +1858,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h struct wined3d_vertex_declaration *vertex_declaration; struct wined3d_stream_output stream_output[MAX_STREAM_OUT]; -@@ -2029,6 +2092,7 @@ +@@ -2028,6 +2091,7 @@ DWORD render_states[WINEHIGHEST_RENDER_STATE + 1]; }; @@ -1866,7 +1866,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h struct wined3d_gl_bo { GLuint name; -@@ -2037,6 +2101,7 @@ +@@ -2036,6 +2100,7 @@ UINT size; }; @@ -1874,7 +1874,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h #define WINED3D_UNMAPPED_STAGE ~0U /* Multithreaded flag. Removed from the public header to signal that -@@ -2092,11 +2157,23 @@ +@@ -2091,11 +2156,23 @@ struct wined3d_rendertarget_view *back_buffer_view; struct wined3d_swapchain **swapchains; UINT swapchain_count; @@ -1898,7 +1898,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h /* For rendering to a texture using glCopyTexImage */ GLuint depth_blt_texture; -@@ -2107,6 +2184,9 @@ +@@ -2106,6 +2183,9 @@ UINT xScreenSpace; UINT yScreenSpace; UINT cursorWidth, cursorHeight; @@ -1908,7 +1908,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h HCURSOR hardwareCursor; /* The Wine logo texture */ -@@ -2138,6 +2218,7 @@ +@@ -2137,6 +2217,7 @@ UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN; void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN; @@ -1916,7 +1916,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN; void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask) DECLSPEC_HIDDEN; void device_exec_update_texture(struct wined3d_context *context, struct wined3d_texture *src_texture, -@@ -2149,6 +2230,11 @@ +@@ -2148,6 +2229,11 @@ void device_create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; void device_delete_opengl_contexts_cs(struct wined3d_device *device, struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; @@ -1928,7 +1928,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state) { -@@ -2165,9 +2251,11 @@ +@@ -2164,9 +2250,11 @@ ULONG (*resource_incref)(struct wined3d_resource *resource); ULONG (*resource_decref)(struct wined3d_resource *resource); void (*resource_unload)(struct wined3d_resource *resource); @@ -1940,7 +1940,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h }; struct wined3d_resource -@@ -2192,6 +2280,7 @@ +@@ -2191,6 +2279,7 @@ UINT depth; UINT size; DWORD priority; @@ -1948,7 +1948,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h void *heap_memory, *map_heap_memory, *user_memory, *bitmap_data; UINT custom_row_pitch, custom_slice_pitch; struct wined3d_gl_bo *buffer, *map_buffer; -@@ -2199,6 +2288,11 @@ +@@ -2198,6 +2287,11 @@ DWORD locations; LONG access_fence; BOOL unmap_dirtify; @@ -1960,7 +1960,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h void *parent; const struct wined3d_parent_ops *parent_ops; -@@ -2223,6 +2317,7 @@ +@@ -2222,6 +2316,7 @@ void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN; void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN; @@ -1968,7 +1968,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h DWORD wined3d_resource_access_from_location(DWORD location) DECLSPEC_HIDDEN; BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_resource_changed(struct wined3d_resource *resource, -@@ -2269,6 +2364,15 @@ +@@ -2268,6 +2363,15 @@ { while(InterlockedCompareExchange(&resource->access_fence, 0, 0)); } @@ -1984,7 +1984,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h /* Tests show that the start address of resources is 32 byte aligned */ #define RESOURCE_ALIGNMENT 16 -@@ -2353,7 +2457,9 @@ +@@ -2352,7 +2456,9 @@ void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture, const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; @@ -1994,7 +1994,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h void wined3d_texture_bind(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN; void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, -@@ -2387,9 +2493,16 @@ +@@ -2386,9 +2492,16 @@ struct wined3d_resource resource; struct wined3d_texture *container; @@ -2011,7 +2011,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h }; static inline struct wined3d_volume *volume_from_resource(struct wined3d_resource *resource) -@@ -2397,6 +2510,7 @@ +@@ -2396,6 +2509,7 @@ return CONTAINING_RECORD(resource, struct wined3d_volume, resource); } @@ -2019,7 +2019,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN; void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN; -@@ -2409,6 +2523,23 @@ +@@ -2408,6 +2522,23 @@ struct wined3d_surface_dib { HBITMAP DIBsection; @@ -2043,7 +2043,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h UINT bitmap_size; }; -@@ -2434,7 +2565,11 @@ +@@ -2433,7 +2564,11 @@ struct wined3d_surface_ops { HRESULT (*surface_private_setup)(struct wined3d_surface *surface); @@ -2055,7 +2055,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h }; struct wined3d_surface -@@ -2442,12 +2577,25 @@ +@@ -2441,12 +2576,25 @@ struct wined3d_resource resource; const struct wined3d_surface_ops *surface_ops; struct wined3d_texture *container; @@ -2081,7 +2081,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h GLuint rb_multisample; GLuint rb_resolved; GLenum texture_target; -@@ -2491,10 +2639,19 @@ +@@ -2490,10 +2638,19 @@ GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) DECLSPEC_HIDDEN; void surface_get_drawable_size(const struct wined3d_surface *surface, const struct wined3d_context *context, unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN; @@ -2101,7 +2101,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN; void surface_prepare_rb(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, BOOL multisample) DECLSPEC_HIDDEN; -@@ -2506,6 +2663,7 @@ +@@ -2505,6 +2662,7 @@ const struct wined3d_gl_info *gl_info, void *mem, unsigned int pitch) DECLSPEC_HIDDEN; HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point, struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN; @@ -2109,7 +2109,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc, GLenum target, unsigned int level, unsigned int layer, DWORD flags, struct wined3d_surface **surface) DECLSPEC_HIDDEN; -@@ -2524,6 +2682,21 @@ +@@ -2523,6 +2681,21 @@ void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; void surface_flip(struct wined3d_surface *front, struct wined3d_surface *back) DECLSPEC_HIDDEN; @@ -2131,7 +2131,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h /* Surface flags: */ #define SFLAG_DIBSECTION 0x00000001 /* Has a DIB section attached for GetDC. */ -@@ -2571,8 +2744,10 @@ +@@ -2570,8 +2743,10 @@ BOOL half_float_conv_needed; }; @@ -2142,7 +2142,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h struct wined3d_saved_states { DWORD transform[(HIGHEST_TRANSFORMSTATE >> 5) + 1]; -@@ -2640,6 +2815,7 @@ +@@ -2639,6 +2814,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN; void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; @@ -2150,7 +2150,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h HRESULT state_init(struct wined3d_state *state, const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN; -@@ -2690,6 +2866,32 @@ +@@ -2689,6 +2865,32 @@ void wined3d_cs_destroy(struct wined3d_cs *cs) DECLSPEC_HIDDEN; void wined3d_cs_switch_onscreen_ds(struct wined3d_cs *cs, struct wined3d_context *context, struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; @@ -2183,7 +2183,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; -@@ -2739,6 +2941,7 @@ +@@ -2738,6 +2940,7 @@ void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs, struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN; @@ -2191,7 +2191,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h void wined3d_cs_emit_set_consts_f(struct wined3d_cs *cs, UINT start_register, const float *constants, UINT vector4f_count, enum wined3d_shader_type type) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_consts_b(struct wined3d_cs *cs, UINT start_register, -@@ -2798,6 +3001,7 @@ +@@ -2797,6 +3000,7 @@ struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; void wined3d_cs_emit_getdc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; void wined3d_cs_emit_releasedc(struct wined3d_cs *cs, struct wined3d_surface *surface) DECLSPEC_HIDDEN; @@ -2199,7 +2199,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h /* Direct3D terminology with little modifications. We do not have an issued state * because only the driver knows about it, but we have a created state because d3d -@@ -2812,8 +3016,12 @@ +@@ -2811,8 +3015,12 @@ struct wined3d_query_ops { HRESULT (*query_get_data)(struct wined3d_query *query, void *data, DWORD data_size, DWORD flags); @@ -2212,7 +2212,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h }; struct wined3d_query -@@ -2827,12 +3035,16 @@ +@@ -2826,12 +3034,16 @@ enum wined3d_query_type type; DWORD data_size; void *extendedData; @@ -2229,7 +2229,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other * fixed function semantics as D3DCOLOR or FLOAT16 */ -@@ -2859,7 +3071,9 @@ +@@ -2858,7 +3070,9 @@ GLenum buffer_object_usage; GLenum buffer_type_hint; DWORD flags; @@ -2239,7 +2239,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h void *map_ptr; struct wined3d_map_range *maps; -@@ -2884,11 +3098,15 @@ +@@ -2883,11 +3097,15 @@ BYTE *buffer_get_sysmem(struct wined3d_buffer *This, struct wined3d_context *context) DECLSPEC_HIDDEN; void buffer_internal_preload(struct wined3d_buffer *buffer, struct wined3d_context *context, const struct wined3d_state *state) DECLSPEC_HIDDEN; @@ -2255,7 +2255,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h struct wined3d_rendertarget_view { -@@ -2927,8 +3145,10 @@ +@@ -2926,8 +3144,10 @@ return surface_from_resource(resource); } @@ -2266,7 +2266,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h struct wined3d_shader_resource_view { LONG refcount; -@@ -2941,8 +3161,12 @@ +@@ -2940,8 +3160,12 @@ struct wined3d_swapchain_ops { void (*swapchain_present)(struct wined3d_swapchain *swapchain, const RECT *src_rect, @@ -2279,7 +2279,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h }; struct wined3d_swapchain -@@ -2982,8 +3206,10 @@ +@@ -2981,8 +3205,10 @@ HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; @@ -2290,7 +2290,7 @@ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h /***************************************************************************** * Utility function prototypes -@@ -3187,7 +3413,9 @@ +@@ -3186,7 +3412,9 @@ void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_string_buffer *buffer, const struct wined3d_shader_reg_maps *reg_maps, const DWORD *byte_code, void *backend_ctx) DECLSPEC_HIDDEN; BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage usage) DECLSPEC_HIDDEN; @@ -4512,7 +4512,7 @@ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c -@@ -1546,9 +1546,17 @@ +@@ -1548,9 +1548,17 @@ const struct wined3d_shader_reg_maps *reg_maps, const struct shader_glsl_ctx_priv *ctx_priv) { const struct wined3d_shader_version *version = ®_maps->shader_version; @@ -4530,7 +4530,7 @@ diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c unsigned int i, extra_constants_needed = 0; const struct wined3d_shader_lconst *lconst; const char *prefix; -@@ -1808,7 +1816,11 @@ +@@ -1810,7 +1818,11 @@ { UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input); @@ -4542,7 +4542,7 @@ diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c shader_addline(buffer, "varying vec4 %s_link[%u];\n", prefix, in_count); shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count); } -@@ -1849,6 +1861,7 @@ +@@ -1851,6 +1863,7 @@ } else { @@ -4550,7 +4550,7 @@ diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c /* This happens because we do not have proper tracking of the * constant registers that are actually used, only the max * limit of the shader version. -@@ -1857,6 +1870,23 @@ +@@ -1859,6 +1872,23 @@ * it and just create the uniform. */ FIXME("Cannot find a free uniform for vpos correction params\n"); @@ -9614,7 +9614,7 @@ diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c -@@ -5353,9 +5353,15 @@ +@@ -5395,9 +5395,15 @@ DebugBreak(); }