summaryrefslogtreecommitdiff
path: root/source4/librpc/ndr
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-03-30 10:48:52 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:11:20 -0500
commit0403e2032b258d25f6ff744029c3a0327cebda5a (patch)
tree76ddaddc52c9c7bc19986739995d4d8e19757c53 /source4/librpc/ndr
parent4581134bf5c9c348ba56fea3886c58234774f522 (diff)
downloadsamba-0403e2032b258d25f6ff744029c3a0327cebda5a.tar.gz
samba-0403e2032b258d25f6ff744029c3a0327cebda5a.tar.bz2
samba-0403e2032b258d25f6ff744029c3a0327cebda5a.zip
r6129: - add our own MSZIP decompression implementation
(taken from cabextract.c from KDE) this code maybe need to be rewritten and the compression side needs to be done, but for now it seems to works - remove the dependency to zlib metze (This used to be commit 5e8558c5b4365a494aa054c3e08d4084b319e6e5)
Diffstat (limited to 'source4/librpc/ndr')
-rw-r--r--source4/librpc/ndr/libndr.h2
-rw-r--r--source4/librpc/ndr/ndr_compression.c153
2 files changed, 56 insertions, 99 deletions
diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h
index 3cc25b0ef2..15ac1b2d4c 100644
--- a/source4/librpc/ndr/libndr.h
+++ b/source4/librpc/ndr/libndr.h
@@ -162,7 +162,7 @@ enum ndr_err_code {
};
enum ndr_compression_alg {
- NDR_COMPRESSION_ZLIB
+ NDR_COMPRESSION_MSZIP
};
/*
diff --git a/source4/librpc/ndr/ndr_compression.c b/source4/librpc/ndr/ndr_compression.c
index f09007a715..c806f62189 100644
--- a/source4/librpc/ndr/ndr_compression.c
+++ b/source4/librpc/ndr/ndr_compression.c
@@ -21,27 +21,20 @@
*/
#include "includes.h"
+#include "lib/compression/mszip.h"
-#ifdef HAVE_ZLIB
-#include <zlib.h>
-
-static NTSTATUS ndr_pull_compression_zlib_chunk(struct ndr_pull *ndrpull,
- struct ndr_push *ndrpush,
- struct z_stream_s *zs, int i)
+static NTSTATUS ndr_pull_compression_mszip_chunk(struct ndr_pull *ndrpull,
+ struct ndr_push *ndrpush,
+ struct decomp_state *decomp_state)
{
- uint8_t *comp_chunk;
+ DATA_BLOB comp_chunk;
uint32_t comp_chunk_offset;
uint32_t comp_chunk_size;
- uint8_t *plain_chunk;
+ DATA_BLOB plain_chunk;
uint32_t plain_chunk_offset;
uint32_t plain_chunk_size;
- uint8_t C_CK_marker;
- uint8_t K_CK_marker;
int ret;
- /* I don't know why, this is needed... --metze */
- if (i == 5) ndrpull->offset -=4;
-
NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &plain_chunk_size));
if (plain_chunk_size > 0x00008000) {
return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad ZLIB plain chunk size %08X > 0x00008000 (PULL)",
@@ -50,42 +43,23 @@ static NTSTATUS ndr_pull_compression_zlib_chunk(struct ndr_pull *ndrpull,
NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &comp_chunk_size));
- NDR_CHECK(ndr_pull_uint8(ndrpull, NDR_SCALARS, &C_CK_marker));
- NDR_CHECK(ndr_pull_uint8(ndrpull, NDR_SCALARS, &K_CK_marker));
- if (!(C_CK_marker == (uint8_t)'C' && K_CK_marker == (uint8_t)'K')) {
- return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad ZLIB invalid CK marker C[%02X] K[%02X] (PULL)",
- C_CK_marker, K_CK_marker);
- }
-
DEBUG(10,("plain_chunk_size: %08X (%u) comp_chunk_size: %08X (%u)\n",
plain_chunk_size, plain_chunk_size, comp_chunk_size, comp_chunk_size));
comp_chunk_offset = ndrpull->offset;
NDR_CHECK(ndr_pull_advance(ndrpull, comp_chunk_size));
- comp_chunk = ndrpull->data + comp_chunk_offset;
+ comp_chunk.length = comp_chunk_size;
+ comp_chunk.data = ndrpull->data + comp_chunk_offset;
plain_chunk_offset = ndrpush->offset;
NDR_CHECK(ndr_push_zero(ndrpush, plain_chunk_size));
- plain_chunk = ndrpush->data + plain_chunk_offset;
-
- dump_data(10, comp_chunk, 16);
-
- zs->avail_in = comp_chunk_size;
- zs->next_in = comp_chunk;
- zs->next_out = plain_chunk;
- zs->avail_out = plain_chunk_size;
-
- while (True) {
- ret = inflate(zs, Z_BLOCK);
- if (ret == Z_STREAM_END) {
- DEBUG(0,("comp_chunk_size: %u avail_in: %d, plain_chunk_size: %u, avail_out: %d\n",
- comp_chunk_size, zs->avail_in, plain_chunk_size, zs->avail_out));
- break;
- }
- if (ret != Z_OK) {
- return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad ZLIB (PULL) inflate error %d",
+ plain_chunk.length = plain_chunk_size;
+ plain_chunk.data = ndrpush->data + plain_chunk_offset;
+
+ ret = ZIPdecompress(decomp_state, &comp_chunk, &plain_chunk);
+ if (ret != DECR_OK) {
+ return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad ZIBdecompress() error %d (PULL)",
ret);
- }
}
if ((plain_chunk_size < 0x00008000) || (ndrpull->offset+4 >= ndrpull->data_size)) {
@@ -96,84 +70,71 @@ static NTSTATUS ndr_pull_compression_zlib_chunk(struct ndr_pull *ndrpull,
return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
-static NTSTATUS ndr_pull_compression_zlib(struct ndr_pull *subndr,
- struct ndr_pull *comndr,
- ssize_t decompressed_len)
+static NTSTATUS ndr_pull_compression_mszip(struct ndr_pull *subndr,
+ struct ndr_pull *comndr,
+ ssize_t decompressed_len)
{
NTSTATUS status = NT_STATUS_MORE_PROCESSING_REQUIRED;
struct ndr_push *ndrpush;
DATA_BLOB uncompressed;
- struct z_stream_s zs;
- int ret;
- int i = 0;
-
- ZERO_STRUCT(zs);
+ uint32_t payload_header[4];
+ uint32_t payload_size;
+ uint32_t payload_offset;
+ uint8_t *payload;
+ struct decomp_state *decomp_state;
ndrpush = ndr_push_init_ctx(subndr);
NT_STATUS_HAVE_NO_MEMORY(ndrpush);
- ret = inflateInit2(&zs, -15);
- if (ret != Z_OK) {
- return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad ZLIB (PULL) inflateInit2 error %d",
- ret);
- }
+ decomp_state = ZIPdecomp_state(subndr);
+ NT_STATUS_HAVE_NO_MEMORY(decomp_state);
while (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
- status = ndr_pull_compression_zlib_chunk(subndr, ndrpush, &zs, i++);
+ status = ndr_pull_compression_mszip_chunk(subndr, ndrpush, decomp_state);
}
- inflateEnd(&zs);
NT_STATUS_NOT_OK_RETURN(status);
uncompressed = ndr_push_blob(ndrpush);
+ if (uncompressed.length != decompressed_len) {
+ return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad uncompressed_len [%u] != [%d] (PULL)",
+ uncompressed.length, decompressed_len);
+ }
+
*comndr = *subndr;
comndr->data = uncompressed.data;
comndr->data_size = uncompressed.length;
comndr->offset = 0;
- return NT_STATUS_OK;
-}
+ NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[0]));
+ NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[1]));
+ NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[2]));
+ NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[3]));
-static NTSTATUS ndr_push_compression_zlib(struct ndr_push *subndr,
- struct ndr_push *comndr)
-{
- DATA_BLOB inbuf;
- DATA_BLOB outbuf = data_blob_talloc(comndr, NULL, comndr->offset + 10);
- struct z_stream_s zs;
- int ret;
+ payload_size = payload_header[2];
- ZERO_STRUCT(zs);
-
- inbuf = ndr_push_blob(comndr);
-
- zs.avail_in = inbuf.length;
- zs.next_in = inbuf.data;
- zs.next_out = outbuf.data+10;
- zs.avail_out = outbuf.length-10;
-
- ret = deflateInit(&zs, Z_DEFAULT_COMPRESSION);
- if (ret != Z_OK) {
- return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Bad ZLIB (PUSH) deflateInit2 error %d",
- ret);
- }
-
- ret = deflate(&zs, Z_SYNC_FLUSH);
-
- if (ret != Z_OK && ret != Z_STREAM_END) {
- return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Bad ZLIB (PULL) deflate error %d",
- ret);
+ /* TODO: check the first 4 bytes of the header */
+ if (payload_header[1] != 0xCCCCCCCC) {
+ return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad payload_header[1] [0x%08X] != [0xCCCCCCCC] (PULL)",
+ payload_header[1]);
}
- deflateEnd(&zs);
+ payload_offset = comndr->offset;
+ NDR_CHECK(ndr_pull_advance(comndr, payload_size));
+ payload = comndr->data + payload_offset;
- /* TODO: push the header here */
-
-
- NDR_CHECK(ndr_push_bytes(subndr, outbuf.data, outbuf.length));
+ comndr->data = payload;
+ comndr->data_size = payload_size;
+ comndr->offset = 0;
return NT_STATUS_OK;
}
-#endif
+
+static NTSTATUS ndr_push_compression_mszip(struct ndr_push *subndr,
+ struct ndr_push *comndr)
+{
+ return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Bad MSZIP compression is not supported yet (PUSH)");
+}
/*
handle compressed subcontext buffers, which in midl land are user-marshalled, but
@@ -187,10 +148,8 @@ NTSTATUS ndr_pull_compression(struct ndr_pull *subndr,
comndr->flags = subndr->flags;
switch (compression_alg) {
-#ifdef HAVE_ZLIB
- case NDR_COMPRESSION_ZLIB:
- return ndr_pull_compression_zlib(subndr, comndr, decompressed_len);
-#endif
+ case NDR_COMPRESSION_MSZIP:
+ return ndr_pull_compression_mszip(subndr, comndr, decompressed_len);
default:
return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad compression algorithm %d (PULL)",
compression_alg);
@@ -208,10 +167,8 @@ NTSTATUS ndr_push_compression(struct ndr_push *subndr,
comndr->flags = subndr->flags;
switch (compression_alg) {
-#ifdef HAVE_ZLIB
- case NDR_COMPRESSION_ZLIB:
- return ndr_push_compression_zlib(subndr, comndr);
-#endif
+ case NDR_COMPRESSION_MSZIP:
+ return ndr_push_compression_mszip(subndr, comndr);
default:
return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Bad compression algorithm %d (PUSH)",
compression_alg);