>From 3752ecbdc59ebdcef0c8620718f134b22be6ee50 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 29 Jun 2016 12:47:18 +0100 Subject: [PATCH 01/10] s4/librpc: Implement a custom dcerpc_binding_handle for rawpipe Intended to be used by clients of raw pipe services. Signed-off-by: Noel Power --- source4/librpc/rpc/dcerpc_raw.c | 382 ++++++++++++++++++++++++++++++++++++++++ source4/librpc/rpc/dcerpc_raw.h | 6 + source4/librpc/wscript_build | 2 +- 3 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 source4/librpc/rpc/dcerpc_raw.c create mode 100644 source4/librpc/rpc/dcerpc_raw.h diff --git a/source4/librpc/rpc/dcerpc_raw.c b/source4/librpc/rpc/dcerpc_raw.c new file mode 100644 index 0000000..ac46be0 --- /dev/null +++ b/source4/librpc/rpc/dcerpc_raw.c @@ -0,0 +1,382 @@ +#include "includes.h" +#include "system/filesys.h" +#include "librpc/rpc/dcerpc_raw.h" +#include "lib/events/events.h" +#include "librpc/rpc/dcerpc.h" +#include "librpc/rpc/dcerpc_proto.h" +#include "param/param.h" +#include "lib/util/tevent_ntstatus.h" +#include "librpc/rpc/rpc_common.h" +#include "lib/tsocket/tsocket.h" + +struct rawpipe_bh_state { + struct dcerpc_pipe *p; +}; + +static bool rawpipe_bh_ref_alloc(struct dcerpc_binding_handle *h) +{ + return true; +} + +static bool rawpipe_bh_is_connected(struct dcerpc_binding_handle *h) +{ + struct rawpipe_bh_state *hs = dcerpc_binding_handle_data(h, + struct rawpipe_bh_state); + + if (!hs->p) { + return false; + } + + if (!hs->p->conn) { + return false; + } + + if (hs->p->conn->dead) { + return false; + } + + return true; +} + +static uint32_t rawpipe_bh_set_timeout(struct dcerpc_binding_handle *h, + uint32_t timeout) +{ + struct rawpipe_bh_state *hs = dcerpc_binding_handle_data(h, + struct rawpipe_bh_state); + uint32_t old; + + if (!hs->p) { + return DCERPC_REQUEST_TIMEOUT; + } + + old = hs->p->request_timeout; + hs->p->request_timeout = timeout; + + return old; +} + +static void rawpipe_bh_auth_info(struct dcerpc_binding_handle *h, + enum dcerpc_AuthType *auth_type, + enum dcerpc_AuthLevel *auth_level) +{ + struct rawpipe_bh_state *hs = dcerpc_binding_handle_data(h, + struct rawpipe_bh_state); + if (hs->p == NULL) { + return; + } + + if (hs->p->conn == NULL) { + return; + } + + *auth_type = hs->p->conn->security_state.auth_type; + *auth_level = hs->p->conn->security_state.auth_level; +} + +struct rawpipe_bh_disconnect_state { + uint8_t _dummy; +}; + +static struct tevent_req *rawpipe_bh_disconnect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct dcerpc_binding_handle *h) +{ + struct rawpipe_bh_state *hs = dcerpc_binding_handle_data(h, + struct rawpipe_bh_state); + struct tevent_req *req; + struct dcerpc_bh_disconnect_state *state; + bool ok; + + req = tevent_req_create(mem_ctx, &state, + struct rawpipe_bh_disconnect_state); + if (req == NULL) { + return NULL; + } + + ok = rawpipe_bh_is_connected(h); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); + return tevent_req_post(req, ev); + } + + /* TODO: do a real disconnect ... */ + hs->p = NULL; + + tevent_req_done(req); + return tevent_req_post(req, ev); +} + +static NTSTATUS rawpipe_bh_disconnect_recv(struct tevent_req *req) +{ + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + tevent_req_received(req); + return NT_STATUS_OK; +} + +struct rawpipe_bh_raw_call_state { + DATA_BLOB out_data; + struct iovec req; + struct iovec resp; + struct tevent_context *ev; + struct dcecli_connection *conn; +}; + +struct rpc_write_state { + struct tevent_context *ev; + DATA_BLOB buffer; + struct dcecli_connection *conn; + struct iovec in; + struct iovec out; +}; + +static void raw_tstream_trans_writev(struct tevent_req *subreq); +static void raw_tstream_trans_readv_done(struct tevent_req *subreq); + +static struct tevent_req *raw_pipe_req_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct dcerpc_pipe *p, + struct iovec *req_data) +{ + struct tevent_req *req, *subreq; + struct rpc_write_state *state; + struct timeval endtime; + + req = tevent_req_create(mem_ctx, &state, struct rpc_write_state); + if (req == NULL) { + return NULL; + } + + /* + * #TODO check if stream is connected + */ + + state->ev = ev; + state->conn = p->conn; + state->in = *req_data; + + endtime = timeval_current_ofs_msec(p->request_timeout); + + subreq = tstream_writev_queue_send(state, + ev, + state->conn->transport.stream, + state->conn->transport.write_queue, + &state->in, + 1); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + + if (!tevent_req_set_endtime(subreq, ev, endtime)) { + return tevent_req_post(req, ev); + } + + tevent_req_set_callback(subreq, raw_tstream_trans_writev, req); + state->buffer.data = talloc_array(state, uint8_t, 1); + state->buffer.length = talloc_array_length(state->buffer.data); + state->out.iov_base = state->buffer.data; + state->out.iov_len = state->buffer.length; + subreq = tstream_readv_send(state, ev, + p->conn->transport.stream, + &state->out, + 1); + + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + if (!tevent_req_set_endtime(subreq, ev, endtime)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, raw_tstream_trans_readv_done, req); + + return req; +} + +static void raw_tstream_trans_readv_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + + struct rpc_write_state *state = + tevent_req_data(req, + struct rpc_write_state); + + int ret; + int err = 0; + int to_read; + ssize_t ofs = 0; + + ret = tstream_readv_recv(subreq, &err); + TALLOC_FREE(subreq); + if (ret == -1) { + tevent_req_nterror(req, map_nt_error_from_unix_common(err)); + return; + } + + to_read = tstream_pending_bytes(state->conn->transport.stream); + if (!to_read) { + /* we're done */ + tevent_req_done(req); + return; + } + + ofs = state->buffer.length; + state->buffer.data = talloc_realloc(state, + state->buffer.data, + uint8_t, + to_read + ofs); + state->buffer.length = to_read + state->buffer.length; + state->out.iov_base = (void *) (state->buffer.data + ofs); + state->out.iov_len = state->buffer.length - ofs; + subreq = tstream_readv_send(state, + state->ev, + state->conn->transport.stream, + &state->out, + 1); + if (tevent_req_nomem(subreq, req)) { + tevent_req_post(req, state->ev); + return; + } + + tevent_req_set_callback(subreq, raw_tstream_trans_readv_done, req); +} + +static void raw_tstream_trans_writev(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + int ret; + int err; + ret = tstream_writev_queue_recv(subreq, &err); + TALLOC_FREE(subreq); + if (ret == -1) { + tevent_req_nterror(req, map_nt_error_from_unix_common(err)); + return; + } +} + +static void rawpipe_bh_call_send_done(struct tevent_req *subreq); +static struct tevent_req *rawpipe_bh_call_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct dcerpc_binding_handle *h, + const struct GUID *object, + uint32_t opnum, + uint32_t in_flags, + const uint8_t *in_data, + size_t in_length) +{ + struct rawpipe_bh_state *hs = dcerpc_binding_handle_data(h, + struct rawpipe_bh_state); + struct tevent_req *req; + bool ok; + struct tevent_req *subreq; + struct rawpipe_bh_raw_call_state* state; + + req = tevent_req_create(mem_ctx, &state, + struct rawpipe_bh_raw_call_state); + if (req == NULL) { + return NULL; + } + state->req.iov_len = in_length; + state->req.iov_base = discard_const_p(uint8_t, in_data); + + state->out_data = data_blob_null; + state->conn = hs->p->conn; + state->ev = ev; + + ok = rawpipe_bh_is_connected(h); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); + return tevent_req_post(req, ev); + } + subreq = raw_pipe_req_send(state, ev, hs->p, + &state->req); + + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, rawpipe_bh_call_send_done, req); + return req; +} + +static void rawpipe_bh_call_send_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct rawpipe_bh_raw_call_state *state = + tevent_req_data(req, + struct rawpipe_bh_raw_call_state); + struct rpc_write_state *write_state = + tevent_req_data(subreq, + struct rpc_write_state); + NTSTATUS status; + if (tevent_req_is_nterror(subreq, &status)) { + tevent_req_nterror(req, status); + return; + } + state->out_data.data = talloc_move(state, &write_state->buffer.data); + state->out_data.length = write_state->buffer.length; + TALLOC_FREE(subreq); + tevent_req_done(req); +} + +static NTSTATUS rawpipe_bh_call_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + uint8_t **out_data, + size_t *out_length, + uint32_t *out_flags) +{ + NTSTATUS status; + struct rawpipe_bh_raw_call_state *state = + tevent_req_data(req, + struct rawpipe_bh_raw_call_state); + + *out_data = talloc_move(mem_ctx, &state->out_data.data); + *out_length = state->out_data.length; + status = NT_STATUS_OK; + if (tevent_req_is_nterror(req, &status)) { + } + tevent_req_received(req); + + return status; +} + +static const struct dcerpc_binding_handle_ops raw_pipe_ccli_bh_ops = { + .name = "raw_pipe_ccli", + .is_connected = rawpipe_bh_is_connected, + .set_timeout = rawpipe_bh_set_timeout, + .auth_info = rawpipe_bh_auth_info, + .raw_call_send = rawpipe_bh_call_send, + .raw_call_recv = rawpipe_bh_call_recv, + .disconnect_send = rawpipe_bh_disconnect_send, + .disconnect_recv = rawpipe_bh_disconnect_recv, + + .ref_alloc = rawpipe_bh_ref_alloc, +}; + +struct dcerpc_binding_handle *create_rawpipe_handle(struct dcerpc_pipe *p) +{ + struct dcerpc_binding_handle *h = NULL; + + struct rawpipe_bh_state *hs; + h = dcerpc_binding_handle_create(p, + &raw_pipe_ccli_bh_ops, + NULL, + NULL, + &hs, + struct rawpipe_bh_state, + __location__); + if (h == NULL) { + return NULL; + } + hs->p = p; + return h; +} diff --git a/source4/librpc/rpc/dcerpc_raw.h b/source4/librpc/rpc/dcerpc_raw.h new file mode 100644 index 0000000..2c53b0d --- /dev/null +++ b/source4/librpc/rpc/dcerpc_raw.h @@ -0,0 +1,6 @@ +#ifndef __DCERPC_RAW_H__ +#define __DCERPC_RAW_H__ +struct dcerpc_pipe; +struct dcerpc_binding_handle; +struct dcerpc_binding_handle *create_rawpipe_handle(struct dcerpc_pipe *p); +#endif /* __DCERPC_RAW_H__ */ diff --git a/source4/librpc/wscript_build b/source4/librpc/wscript_build index 77d1777..0f97cc5 100755 --- a/source4/librpc/wscript_build +++ b/source4/librpc/wscript_build @@ -109,7 +109,7 @@ bld.SAMBA_LIBRARY('dcerpc', source='''rpc/dcerpc.c rpc/dcerpc_auth.c rpc/dcerpc_schannel.c rpc/dcerpc_util.c rpc/dcerpc_smb.c rpc/dcerpc_sock.c rpc/dcerpc_roh_channel_in.c rpc/dcerpc_roh_channel_out.c rpc/dcerpc_roh.c - rpc/dcerpc_connect.c rpc/dcerpc_secondary.c''', + rpc/dcerpc_connect.c rpc/dcerpc_secondary.c rpc/dcerpc_raw.c''', pc_files='dcerpc.pc', deps='samba_socket LIBCLI_RESOLVE LIBCLI_SMB LIBCLI_SMB2 ndr NDR_DCERPC RPC_NDR_EPMAPPER NDR_SCHANNEL RPC_NDR_NETLOGON RPC_NDR_MGMT gensec LIBCLI_AUTH smbclient-raw LP_RESOLVE tevent-util dcerpc-binding param_options http', autoproto='rpc/dcerpc_proto.h', -- 2.10.2 >From d15e010504d6c977adec50f33e2d1fc85b39d3d7 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 5 Jun 2014 10:52:54 +0100 Subject: [PATCH 02/10] libcli/smb: Allow dynamic setting of the max_data in SMB Pipe transaction. Some services like WSP can send larger messages than the current 'Max Ioctl' limit, this results in the server producing a BUFFER_OVERFLOW status (and additionally clipping the message sent). Add support to allow a client to modify the hardcoded 'Max Ioctl' default value to allow the server to successfully send larger responses. Signed-off-by: Noel Power --- libcli/smb/tstream_smbXcli_np.c | 33 +++++++++++++++++++++++++-------- libcli/smb/tstream_smbXcli_np.h | 3 +++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/libcli/smb/tstream_smbXcli_np.c b/libcli/smb/tstream_smbXcli_np.c index a59db13..1ffde42 100644 --- a/libcli/smb/tstream_smbXcli_np.c +++ b/libcli/smb/tstream_smbXcli_np.c @@ -57,6 +57,7 @@ struct tstream_smbXcli_np { uint16_t fnum; uint64_t fid_persistent; uint64_t fid_volatile; + uint32_t max_data; struct { bool active; @@ -358,7 +359,7 @@ NTSTATUS _tstream_smbXcli_np_open_recv(struct tevent_req *req, cli_nps->fnum = state->fnum; cli_nps->fid_persistent = state->fid_persistent; cli_nps->fid_volatile = state->fid_volatile; - + cli_nps->max_data = TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE; talloc_set_destructor(cli_nps, tstream_smbXcli_np_destructor); talloc_set_destructor(cli_nps->conn_ref, tstream_smbXcli_np_ref_destructor); @@ -426,6 +427,14 @@ NTSTATUS tstream_smbXcli_np_use_trans(struct tstream_context *stream) return NT_STATUS_OK; } +void tstream_smbXcli_np_set_max_data(struct tstream_context *stream, + uint32_t max_data) +{ + struct tstream_smbXcli_np *cli_nps = + tstream_context_data(stream, struct tstream_smbXcli_np); + cli_nps->max_data = max_data; +} + unsigned int tstream_smbXcli_np_set_timeout(struct tstream_context *stream, unsigned int timeout) { @@ -524,6 +533,7 @@ static void tstream_smbXcli_np_writev_write_next(struct tevent_req *req) struct tevent_req *subreq; size_t i; size_t left = 0; + uint32_t max_data = cli_nps->max_data; for (i=0; i < state->count; i++) { left += state->vector[i].iov_len; @@ -536,7 +546,7 @@ static void tstream_smbXcli_np_writev_write_next(struct tevent_req *req) } cli_nps->write.ofs = 0; - cli_nps->write.left = MIN(left, TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE); + cli_nps->write.left = MIN(left, max_data); cli_nps->write.buf = talloc_realloc(cli_nps, cli_nps->write.buf, uint8_t, cli_nps->write.left); if (tevent_req_nomem(cli_nps->write.buf, req)) { @@ -803,6 +813,7 @@ static void tstream_smbXcli_np_readv_read_next(struct tevent_req *req) tstream_context_data(state->stream, struct tstream_smbXcli_np); struct tevent_req *subreq; + uint32_t max_data = cli_nps->max_data; /* * copy the pending buffer first @@ -858,14 +869,14 @@ static void tstream_smbXcli_np_readv_read_next(struct tevent_req *req) cli_nps->session, cli_nps->fnum, 0, /* offset */ - TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE); + max_data); } else { subreq = smb2cli_read_send(state, state->ev, cli_nps->conn, cli_nps->timeout, cli_nps->session, cli_nps->tcon, - TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE, /* length */ + max_data, /* length */ 0, /* offset */ cli_nps->fid_persistent, cli_nps->fid_volatile, @@ -891,6 +902,7 @@ static void tstream_smbXcli_np_readv_trans_start(struct tevent_req *req) tstream_context_data(state->stream, struct tstream_smbXcli_np); struct tevent_req *subreq; + uint32_t max_data = cli_nps->max_data; state->trans.im = tevent_create_immediate(state); if (tevent_req_nomem(state->trans.im, req)) { @@ -913,7 +925,7 @@ static void tstream_smbXcli_np_readv_trans_start(struct tevent_req *req) NULL, 0, 0, cli_nps->write.buf, cli_nps->write.ofs, - TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE); + max_data); } else { DATA_BLOB in_input_buffer = data_blob_null; DATA_BLOB in_output_buffer = data_blob_null; @@ -932,7 +944,7 @@ static void tstream_smbXcli_np_readv_trans_start(struct tevent_req *req) 0, /* in_max_input_length */ &in_input_buffer, /* in_max_output_length */ - TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE, + max_data, &in_output_buffer, SMB2_IOCTL_FLAG_IS_FSCTL); } @@ -959,10 +971,14 @@ static void tstream_smbXcli_np_readv_trans_done(struct tevent_req *subreq) tevent_req_data(req, struct tstream_smbXcli_np_readv_state); struct tstream_smbXcli_np *cli_nps = tstream_context_data(state->stream, struct tstream_smbXcli_np); + uint32_t max_data = cli_nps->max_data; uint8_t *rcvbuf; uint32_t received; NTSTATUS status; + /* reset max_data, should be set different every time (if required) */ + cli_nps->max_data = TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE; + if (cli_nps->is_smb1) { status = smb1cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, NULL, 0, NULL, @@ -995,7 +1011,7 @@ static void tstream_smbXcli_np_readv_trans_done(struct tevent_req *subreq) return; } - if (received > TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE) { + if (received > max_data) { tstream_smbXcli_np_readv_disconnect_now(req, EIO, __location__); return; } @@ -1045,6 +1061,7 @@ static void tstream_smbXcli_np_readv_read_done(struct tevent_req *subreq) tevent_req_data(req, struct tstream_smbXcli_np_readv_state); struct tstream_smbXcli_np *cli_nps = tstream_context_data(state->stream, struct tstream_smbXcli_np); + uint32_t max_data = cli_nps->max_data; uint8_t *rcvbuf; uint32_t received; NTSTATUS status; @@ -1079,7 +1096,7 @@ static void tstream_smbXcli_np_readv_read_done(struct tevent_req *subreq) return; } - if (received > TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE) { + if (received > max_data) { TALLOC_FREE(subreq); tstream_smbXcli_np_readv_disconnect_now(req, EIO, __location__); return; diff --git a/libcli/smb/tstream_smbXcli_np.h b/libcli/smb/tstream_smbXcli_np.h index e8c5c39..d7a4e3c 100644 --- a/libcli/smb/tstream_smbXcli_np.h +++ b/libcli/smb/tstream_smbXcli_np.h @@ -69,4 +69,7 @@ unsigned int tstream_smbXcli_np_set_timeout(struct tstream_context *stream, */ #define TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE 4280 +void tstream_smbXcli_np_set_max_data(struct tstream_context *stream, + uint32_t max_data); + #endif /* _CLI_NP_TSTREAM_H_ */ -- 2.10.2 >From 85b29c843e1a0eb2d209c187b33a511b3cf49a4e Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 24 Nov 2016 17:02:32 +0000 Subject: [PATCH 03/10] libcli/smb: Implement SMB2 FSCTL_PIPE_WAIT & SMB1 WaitNamedPipe functions Signed-off-by: Noel Power --- libcli/smb/smbXcli_base.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++ libcli/smb/smbXcli_base.h | 19 +++++ 2 files changed, 202 insertions(+) diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index e24090d..5a37b8b 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -6251,3 +6251,186 @@ bool smb2cli_tcon_is_encryption_on(struct smbXcli_tcon *tcon) { return tcon->smb2.should_encrypt; } + + +struct fsctl_pipe_wait_req +{ + int64_t timeout; + uint32_t namelength; + uint8_t timeout_specified; + const char* name; +}; + +static bool write_pipe_wait_request_data( + struct fsctl_pipe_wait_req *wait_request, + DATA_BLOB *output) +{ + uint8_t *buf = output->data; + uint32_t pos = 0; + /* lenght of data up to pipe name */ + uint32_t min_len = 14; + bool result = false; + + if (output->length < min_len) { + result = false; + goto out; + } + SBVALS(buf, pos, wait_request->timeout); + pos += 8; + + SIVAL(buf, pos, wait_request->namelength); + pos +=4; + + if (min_len + wait_request->namelength > output->length) { + DEBUG(0,("incorrect buffer len, buffer size is %zu but we require %d\n", output->length, min_len + wait_request->namelength)); + result =false; + goto out; + } + + *(buf + pos) = wait_request->timeout_specified; + pos++; + + pos++; /* skip padding */ + + push_string((buf + pos), wait_request->name, + wait_request->namelength, + STR_UNICODE | STR_NOALIGN); + result = true; +out: + return result; +} + +struct smb2cli_wait_pipe_state { + struct smbXcli_conn *conn; + DATA_BLOB in_input_buffer; + DATA_BLOB in_output_buffer; +}; + +static void smb2cli_wait_pipe_done(struct tevent_req *subreq); + +struct tevent_req *smb2cli_wait_pipe_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn, + uint32_t timeout_msec, + struct smbXcli_session *session, + struct smbXcli_tcon *tcon, + int64_t pipe_wait_timeout, + const char *pipe_name) +{ + struct tevent_req *req, *subreq; + struct smb2cli_wait_pipe_state *state; + struct fsctl_pipe_wait_req wait_req; + ZERO_STRUCT(wait_req); + + req = tevent_req_create(mem_ctx, &state, + struct smb2cli_wait_pipe_state); + if (req == NULL) { + return NULL; + } + state->conn = conn; + state->in_input_buffer = data_blob_talloc_zero(state, 14 + strlen(pipe_name) * 2); + wait_req.timeout = pipe_wait_timeout; + wait_req.namelength = strlen(pipe_name) * 2; + + wait_req.timeout_specified = false; + wait_req.name = pipe_name; + + if (!write_pipe_wait_request_data(&wait_req, &state->in_input_buffer)) { + return tevent_req_post(req, ev); + } + subreq = smb2cli_ioctl_send(state, ev, conn, + timeout_msec, session, tcon, + UINT64_MAX, /* in_fid_persistent */ + UINT64_MAX, /* in_fid_volatile */ + FSCTL_PIPE_WAIT, + 0, /* in_max_input_length */ + &state->in_input_buffer, + 0, /* in_max_output_length */ + &state->in_output_buffer, + SMB2_IOCTL_FLAG_IS_FSCTL); + + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, + smb2cli_wait_pipe_done, + req); + return req; +} + +static void smb2cli_wait_pipe_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct smb2cli_wait_pipe_state *state = + tevent_req_data(req, struct smb2cli_wait_pipe_state); + NTSTATUS status; + + DATA_BLOB out_input_buffer = data_blob_null; + DATA_BLOB out_output_buffer = data_blob_null; + + status = smb2cli_ioctl_recv(subreq, + state, + &out_input_buffer, + &out_output_buffer); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + tevent_req_done(req); +} + + +NTSTATUS smb2cli_wait_pipe_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +struct tevent_req *smb1cli_wait_named_pipe_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn, + uint32_t timeout_msec, + uint32_t pid, + struct smbXcli_session *session, + struct smbXcli_tcon *tcon, + const char *pipe_name) +{ + struct tevent_req *req; + uint16_t function[] = {TRANSACT_WAITNAMEDPIPEHANDLESTATE, 0}; + const char *tmp_pipe_name = pipe_name; + + if (strstr(pipe_name, "\\PIPE\\") != pipe_name) { + tmp_pipe_name = talloc_asprintf(mem_ctx, + "\\PIPE\\%s", + pipe_name); + } + + if (tmp_pipe_name == NULL) { + return NULL; + } + + req = smb1cli_trans_send(mem_ctx, ev, + conn, + SMBtrans, + 0, 0, /* *_flags */ + 0, 0, /* *_flags2 */ + timeout_msec, + pid, + tcon, + session, + tmp_pipe_name, + 0, 0, 0, + function, 2, + 0, + NULL, 0, 0, + NULL, + 0, + 0); + + return req; +} + +NTSTATUS smb1cli_wait_named_pipe_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index 702eedf..f6abd02 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -840,4 +840,23 @@ NTSTATUS smb2cli_echo_recv(struct tevent_req *req); NTSTATUS smb2cli_echo(struct smbXcli_conn *conn, uint32_t timeout_msec); +struct tevent_req *smb2cli_wait_pipe_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn, + uint32_t timeout_msec, + struct smbXcli_session *session, + struct smbXcli_tcon *tcon, + int64_t pipe_wait_timeout, + const char *pipe_name); +NTSTATUS smb2cli_wait_pipe_recv(struct tevent_req *req); +struct tevent_req *smb1cli_wait_named_pipe_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn, + uint32_t timeout_msec, + uint32_t pid, + struct smbXcli_session *session, + struct smbXcli_tcon *tcon, + const char *pipe_name); +NTSTATUS smb1cli_wait_named_pipe_recv(struct tevent_req *req); + #endif /* _SMBXCLI_BASE_H_ */ -- 2.10.2 >From ec44695fd2ad36f614029480d5c1abb3bedfd5fd Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 2 Dec 2014 17:26:41 +0000 Subject: [PATCH 04/10] pidl/lib: Add recursion detection logic to prevent looping. Under some circumstances 'can_contain_deferred' & 'align_type functions' can loop. This prevents a hang when processing sample idl like interface hang { typedef [public] struct { wsp_cbasestoragevariant variant[NUM_ENTRIES]; } vt_variant_wrap; typedef [public,nodiscriminant,switch_type(uint16)] union { [case(VT_I1)] int8 vt_i1; [case(VT_VARIANT)] vt_variant_wrap vt_variant_wrap; } variant_types; typedef [public] struct { [switch_is(vtype)] variant_types vvalue; } wsp_cbasestoragevariant; }; which will hang with the following command pidl --header --ndr-parser -- foo.idl Signed-off-by: Noel Power --- pidl/lib/Parse/Pidl/NDR.pm | 73 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/pidl/lib/Parse/Pidl/NDR.pm b/pidl/lib/Parse/Pidl/NDR.pm index 4659e31..c3be61f 100644 --- a/pidl/lib/Parse/Pidl/NDR.pm +++ b/pidl/lib/Parse/Pidl/NDR.pm @@ -402,16 +402,38 @@ sub can_contain_deferred($) return 0 if (Parse::Pidl::Typelist::is_scalar($type)); - return can_contain_deferred($type->{DATA}) if ($type->{TYPE} eq "TYPEDEF"); + if ( not defined($type->{INCANCONTAINDERRED})) { + $type->{INCANCONTAINDERRED} = 0; + } + + my $res; + + if ($type->{INCANCONTAINDERRED} == 1 ){ + $res = 0; + goto out_recurse; + } - return 0 unless defined($type->{ELEMENTS}); + $type->{INCANCONTAINDERRED} = 1; + if ($type->{TYPE} eq "TYPEDEF") { + $res = can_contain_deferred($type->{DATA}); + goto out; + } + + if (!defined($type->{ELEMENTS})) { + $res = 0; + goto out; + } foreach (@{$type->{ELEMENTS}}) { - return 1 if ($_->{POINTERS}); - return 1 if (can_contain_deferred ($_->{TYPE})); + if (($_->{POINTERS}) || can_contain_deferred ($_->{TYPE})) { + $res = 1; + goto out; + } } - - return 0; +out: + $type->{INCANCONTAINDERRED} = 0; +out_recurse: + return $res; } sub pointer_type($) @@ -481,23 +503,48 @@ sub align_type($) my $dt = getType($e); + if ( not defined($dt->{INGETALIGNTYPE})) { + $dt->{INGETALIGNTYPE} = 0; + } + + my $res; + if ($dt->{INGETALIGNTYPE} == 1 ){ + # reset it + $res = 0; + goto out_recurse; + } + + $dt->{INGETALIGNTYPE} = 1; + if ($dt->{TYPE} eq "TYPEDEF") { - return align_type($dt->{DATA}); + $res = align_type($dt->{DATA}); + goto out; } elsif ($dt->{TYPE} eq "CONFORMANCE") { - return $dt->{DATA}->{ALIGN}; + $res = $dt->{DATA}->{ALIGN}; + goto out; } elsif ($dt->{TYPE} eq "ENUM") { - return align_type(Parse::Pidl::Typelist::enum_type_fn($dt)); + $res = align_type(Parse::Pidl::Typelist::enum_type_fn($dt)); + goto out; } elsif ($dt->{TYPE} eq "BITMAP") { - return align_type(Parse::Pidl::Typelist::bitmap_type_fn($dt)); + $res = align_type(Parse::Pidl::Typelist::bitmap_type_fn($dt)); + goto out; } elsif (($dt->{TYPE} eq "STRUCT") or ($dt->{TYPE} eq "UNION")) { # Struct/union without body: assume 4 - return 4 unless (defined($dt->{ELEMENTS})); - return find_largest_alignment($dt); + $res = 4; + if (defined($dt->{ELEMENTS})) { + $res = find_largest_alignment($dt); + } + goto out; } elsif (($dt->{TYPE} eq "PIPE")) { - return 5; + $res = 5; + goto out; } die("Unknown data type type $dt->{TYPE}"); +out: + $dt->{INGETALIGNTYPE} = 0; +out_recurse: + return $res; } sub ParseElement($$$) -- 2.10.2 >From 2cc668faa43e2caebf72b085ca300b51ad80a2bf Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 25 Aug 2014 11:53:30 +0100 Subject: [PATCH 05/10] pidl/tests: Add tests for hang with nested struct. make sure hang test calls Parse::Pidl::Typelist::LoadIdl which triggers part of the hang Signed-off-by: Noel Power --- pidl/tests/header.pl | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/pidl/tests/header.pl b/pidl/tests/header.pl index db59484..bbd0b58 100755 --- a/pidl/tests/header.pl +++ b/pidl/tests/header.pl @@ -4,7 +4,7 @@ use strict; use warnings; -use Test::More tests => 27; +use Test::More tests => 30; use FindBin qw($RealBin); use lib "$RealBin"; use Util; @@ -23,6 +23,16 @@ sub parse_idl($) return Parse::Pidl::Samba4::Header::Parse($ndr); } +sub load_and_parse_idl($) +{ + my $text = shift; + my $ndr; + my $idl = Parse::Pidl::IDL::parse_string($text, "nofile"); + Parse::Pidl::Typelist::LoadIdl($idl, "noname"); + $ndr = Parse::Pidl::NDR::Parse($idl); + return Parse::Pidl::Samba4::Header::Parse($ndr); +} + like(parse_idl(""), qr/\/\* header auto-generated by pidl \*\/\n/sm, "includes work"); like(parse_idl("interface x {}"), qr/\/\* header auto-generated by pidl \*\/\n/sm, "simple empty interface doesn't cause overhead"); like(parse_idl("interface p { typedef struct { int y; } x; };"), @@ -59,6 +69,15 @@ like(parse_idl("interface p { typedef struct x { int p; } x; };"), like(parse_idl("cpp_quote(\"some-foo\")"), qr/some-foo/sm, "cpp quote"); +like(load_and_parse_idl("interface hang {typedef [public] struct { wsp_cbasestoragevariant a[SINGLE]; } foo; typedef [public,nodiscriminant,switch_type(uint16)] union { [case(VT_I1)] int8 vt_i1; [case(VT_VARIANT)] foo b; } variant_types; typedef [public] struct { [switch_is(vtype)] variant_types vvalue; } bar;};"), + qr/struct foo.*{.*struct wsp_cbasestoragevariant \*a.*struct bar {.*union variant_types vvalue.*;/sm,"test for hang with nested struct with union"); + +like(load_and_parse_idl("interface hang { typedef struct { uint32 count; bar a[count];} foo ; typedef struct { foo b; } bar; };"), + qr/struct foo.*{.*struct bar \*a;/sm,"test for hang with nested struct"); + +like(load_and_parse_idl("interface hang { typedef struct { bar a; } foo ; typedef struct { foo b; } bar; };"), + qr/struct foo.*{.*struct bar a;/sm,"test for hang with uncompilable nested struct"); + # Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work my $fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] }; is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionInEnv($fn)); -- 2.10.2 >From c7037d07bae5730c3f4f3f566af5295fccf6d0b3 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 3 Dec 2014 10:56:18 +0000 Subject: [PATCH 06/10] librpc/idl: Add idl for WSP and also some required helper functions. Represent the message data, structures and constants to do with the WSP (Windows Search Protocol) as idl. (see: https://msdn.microsoft.com/en-us/library/cc251767.aspx) Signed-off-by: Noel Power --- librpc/idl/wscript_build | 2 +- librpc/idl/wsp.idl | 1213 ++++++++++++++++++++++++++++++++++++++++++++++ librpc/idl/wsp_data.idl | 301 ++++++++++++ librpc/rpc/wsp_helper.c | 52 ++ librpc/rpc/wsp_helper.h | 31 ++ librpc/wscript_build | 12 +- 6 files changed, 1609 insertions(+), 2 deletions(-) create mode 100644 librpc/idl/wsp.idl create mode 100644 librpc/idl/wsp_data.idl create mode 100644 librpc/rpc/wsp_helper.c create mode 100644 librpc/rpc/wsp_helper.h diff --git a/librpc/idl/wscript_build b/librpc/idl/wscript_build index 13b29b2..172929a 100644 --- a/librpc/idl/wscript_build +++ b/librpc/idl/wscript_build @@ -35,7 +35,7 @@ bld.SAMBA_PIDL_LIST('PIDL', bld.SAMBA_PIDL_LIST('PIDL', '''rap.idl ntprinting.idl preg.idl ioctl.idl printcap.idl - fsrvp_state.idl''', + fsrvp_state.idl wsp_data.idl wsp.idl''', options='--header --ndr-parser', output_dir='../gen_ndr') diff --git a/librpc/idl/wsp.idl b/librpc/idl/wsp.idl new file mode 100644 index 0000000..2da9699 --- /dev/null +++ b/librpc/idl/wsp.idl @@ -0,0 +1,1213 @@ +#include "idl_types.h" +import "wsp_data.idl"; +import "misc.idl"; + +[ + version(1.0), + helpstring("Windows Search WSP Protocol"), + helper("../librpc/rpc/wsp_helper.h"), + pointer_default(unique) +] + +interface msftewds +{ + /* structs that contain hyper end up having + * an alignment of 8, alignment of 8 e.g. when + * handling wsp_cbstoragevariant doesn't work + * we need to represent the hyper as 2 4 byte + * numbers to ensure the alignment is still 4 + */ + + typedef [public] struct { + uint32 hi; + uint32 lo; + } wsp_hyper; + + typedef [public] struct { + uint32 hi32; + uint32 mid32; + uint32 lo32; + } vt_decimal; + + typedef [public] struct { + uint32 vvector_elements; + vt_decimal vvector_data[vvector_elements]; + } vt_decimal_vec; + /* + * variant elements in a vector (and presumably safearray also) + * must be aligned to 4-byte boundry, think this is automatic for + * elements which are structures + */ + typedef [public] struct { + [value(strlen_m_term(value)*2)] uint32 nbytes; + [flag(STR_NULLTERM)] string value; + } vt_bstr; + + typedef [public] struct { + uint32 vvector_elements; + vt_bstr vvector_data[vvector_elements]; + } vt_bstr_vec; + + typedef [public] struct { + [value(strlen_m_term(value))] uint32 nbytes; + [flag(STR_NULLTERM)] string value; + } vt_lpwstr; + + typedef [public] struct { + uint32 vvector_elements; + vt_lpwstr vvector_data[vvector_elements]; + } vt_lpwstr_vec; + + typedef [public] struct { + uint32 cclen; + uint8 bytes[cclen]; + } vt_compressed_lpwstr; + + typedef [public] struct { + uint32 vvector_elements; + vt_compressed_lpwstr vvector_data[vvector_elements]; + } vt_compressed_lpwstr_vec; + + typedef [public] struct { + uint32 vvector_elements; + int32 vvector_data[vvector_elements]; + } vt_i4_vec; + + typedef [public] struct { + uint32 vvector_elements; + uint32 vvector_data[vvector_elements]; + } vt_ui4_vec; +/* is there some way to specify the above like below instead of having a vector + for each element type e.g. see vt_lpwstr_vec, vt_bstr_vec & vt_i4_vec? + typedef [public] struct { + uint32 num; + variant_types vec[num]; + } vt_vector; +*/ + + typedef [public] struct { + uint32 celements; + uint32 ilbound; + } safearraybound; + + typedef [public] struct { + uint16 cdims; + uint16 ffeatures; + uint32 cbelements; + safearraybound rgsabound[cdims]; + int32 vdata[calc_array_size(rgsabound, cdims)]; + } vt_i4_safe_array; + + typedef [public] struct { + uint16 cdims; + uint16 ffeatures; + uint32 cbelements; + safearraybound rgsabound[cdims]; + uint32 vdata[calc_array_size(rgsabound, cdims)]; + } vt_ui4_safe_array; + + typedef [public] struct { + uint16 cdims; + uint16 ffeatures; + uint32 cbelements; + safearraybound rgsabound[cdims]; + vt_bstr vdata[calc_array_size(rgsabound, cdims)]; + } vt_bstr_safe_array; + + + typedef [public] struct { + uint16 cdims; + uint16 ffeatures; + uint32 cbelements; + safearraybound rgsabound[cdims]; + int8 vdata[calc_array_size(rgsabound, cdims)]; + } vt_i1_safe_array; + + typedef [public] struct { + uint32 vvector_elements; + int8 vvector_data[vvector_elements]; + } vt_i1_vec; + + typedef [public] struct { + uint16 cdims; + uint16 ffeatures; + uint32 cbelements; + safearraybound rgsabound[cdims]; + uint8 vdata[calc_array_size(rgsabound, cdims)]; + } vt_ui1_safe_array; + + typedef [public] struct { + uint32 vvector_elements; + uint8 vvector_data[vvector_elements]; + } vt_ui1_vec; + + typedef [public] struct { + uint16 cdims; + uint16 ffeatures; + uint32 cbelements; + safearraybound rgsabound[cdims]; + int16 vdata[calc_array_size(rgsabound, cdims)]; + } vt_i2_safe_array; + + typedef [public] struct { + uint32 vvector_elements; + int16 vvector_data[vvector_elements]; + } vt_i2_vec; + + typedef [public] struct { + uint16 cdims; + uint16 ffeatures; + uint32 cbelements; + safearraybound rgsabound[cdims]; + uint16 vdata[calc_array_size(rgsabound, cdims)]; + } vt_ui2_safe_array; + + typedef [public] struct { + uint32 vvector_elements; + uint16 vvector_data[vvector_elements]; + } vt_ui2_vec; + + typedef [public] struct { + uint16 cdims; + uint16 ffeatures; + uint32 cbelements; + safearraybound rgsabound[cdims]; + wsp_hyper vdata[calc_array_size(rgsabound, cdims)]; + } vt_wsp_hyper_safe_array; + + typedef [public] struct { + uint32 vvector_elements; + wsp_hyper vvector_data[vvector_elements]; + } vt_wsp_hyper_vec; + + typedef [public] struct { + uint32 vvector_elements; + GUID vvector_data[vvector_elements]; + } vt_clsid_vec; + + typedef [public] struct { + /* + * hack to allow wsp_cbasestoragevariant to be used before + * it is defined + */ + wsp_cbasestoragevariant variant[SINGLE_ITEM]; + } vt_variant_wrap; + + typedef [public] struct { + uint16 cdims; + uint16 ffeatures; + uint32 cbelements; + safearraybound rgsabound[cdims]; + vt_variant_wrap vdata[calc_array_size(rgsabound, cdims)]; + } vt_variant_wrap_safearray; + + typedef [public] struct { + uint32 vvector_elements; + vt_variant_wrap vvector_data[vvector_elements]; + } vt_variant_wrap_vec; + + typedef [public,nodiscriminant,switch_type(uint16)] union { + [case(VT_I1)] int8 vt_i1; + [case(VT_I1 | VT_ARRAY)] vt_i1_safe_array vt_i1_array; + [case(VT_I1 | VT_VECTOR)] vt_i1_vec vt_i1_vec; + + [case(VT_UI1)] uint8 vt_ui1; + [case(VT_UI1 | VT_ARRAY)] vt_ui1_safe_array vt_ui1_array; + [case(VT_UI1 | VT_VECTOR)] vt_ui1_vec vt_ui1_vec; + + [case(VT_I2)] int16 vt_i2; + [case(VT_I2 | VT_ARRAY)] vt_i2_safe_array vt_i2_array; + [case(VT_I2 | VT_VECTOR)] vt_i2_vec vt_i2_vec; + + [case(VT_UI2)] uint16 vt_ui2; + [case(VT_UI2 | VT_ARRAY)] vt_ui2_safe_array vt_ui2_array; + [case(VT_UI2 | VT_VECTOR)] vt_ui2_vec vt_ui2_vec; + + [case(VT_BOOL)] uint16 vt_bool; + [case(VT_BOOL | VT_ARRAY)] vt_ui2_safe_array vt_bool_array; + [case(VT_BOOL | VT_VECTOR)] vt_ui2_vec vt_bool_vec; + + [case(VT_I4)] int32 vt_i4; + [case(VT_I4 | VT_VECTOR)] vt_i4_vec vt_i4_vec; + [case(VT_I4 | VT_ARRAY)] vt_i4_safe_array vt_i4_array; + + [case(VT_UI4)] uint32 vt_ui4; + [case(VT_UI4 | VT_VECTOR)] vt_ui4_vec vt_ui4_vec; + [case(VT_UI4 | VT_ARRAY)] vt_ui4_safe_array vt_ui4_array; + + [case(VT_R4)] uint32 vt_r4; + [case(VT_R4 | VT_VECTOR)] vt_i4_vec vt_r4_vec; + [case(VT_R4 | VT_ARRAY)] vt_i4_safe_array vt_r4_array; + + [case(VT_INT)] int32 vt_int; + [case(VT_INT | VT_ARRAY)] vt_i4_safe_array vt_int_array; + + [case(VT_UINT)] uint32 vt_uint; + [case(VT_UINT | VT_ARRAY)] vt_ui4_safe_array vt_uint_array; + + [case(VT_ERROR)] uint32 vt_error; + [case(VT_ERROR | VT_VECTOR)] vt_ui4_vec vt_error_vec; + [case(VT_ERROR | VT_ARRAY)] vt_ui4_safe_array vt_error_array; + + [case(VT_I8)] wsp_hyper vt_i8; + [case(VT_I8 | VT_VECTOR)] vt_wsp_hyper_vec vt_i8_vec; + + [case(VT_UI8)] wsp_hyper vt_ui8; + [case(VT_UI8 | VT_VECTOR)] vt_wsp_hyper_vec vt_ui8_vec; + + [case(VT_R8)] wsp_hyper vt_r8; + [case(VT_R8 | VT_VECTOR)] vt_wsp_hyper_vec vt_r8_vec; + [case(VT_R8 | VT_ARRAY)] vt_wsp_hyper_safe_array vt_r8_array; + + [case(VT_CY)] wsp_hyper vt_cy; + [case(VT_CY | VT_VECTOR)] vt_wsp_hyper_vec vt_cy_vec; + [case(VT_CY | VT_ARRAY)] vt_wsp_hyper_safe_array vt_cy_array; + + [case(VT_DATE)] wsp_hyper vt_date; + [case(VT_DATE | VT_VECTOR)] vt_wsp_hyper_vec vt_date_vec; + [case(VT_DATE| VT_ARRAY)] vt_wsp_hyper_safe_array vt_date_array; + + [case(VT_FILETIME)] wsp_hyper vt_filetime; + [case(VT_FILETIME | VT_VECTOR)] vt_wsp_hyper_vec vt_filetime_vec; + + [case(VT_BSTR)] vt_bstr vt_bstr; + [case(VT_BSTR | VT_VECTOR)] vt_bstr_vec vt_bstr_v; + [case(VT_BSTR | VT_ARRAY)] vt_bstr_safe_array vt_bstr_array; + + [case(VT_LPWSTR)] vt_lpwstr vt_lpwstr; + [case(VT_LPWSTR | VT_VECTOR)] vt_lpwstr_vec vt_lpwstr_v; + + [case(VT_COMPRESSED_LPWSTR)] vt_compressed_lpwstr vt_compressed_lpwstr; + [case(VT_COMPRESSED_LPWSTR | VT_VECTOR)] vt_compressed_lpwstr_vec vt_compresseed_lpwstr_v; + + [case(VT_DECIMAL)] vt_decimal vt_decimal; + [case(VT_DECIMAL | VT_VECTOR)] vt_decimal_vec vt_decimal_v; + + [case(VT_CLSID)] GUID vt_clid; + [case(VT_CLSID | VT_VECTOR)] vt_clsid_vec vt_clsid_v; + + [case(VT_BLOB)] DATA_BLOB vt_blob; + [case(VT_BLOB_OBJECT)] DATA_BLOB vt_blob_object; + + [case(VT_NULL)]; + [case(VT_EMPTY)]; + + [case(VT_VARIANT)] vt_variant_wrap vt_variant_wrap; + [case(VT_VARIANT | VT_VECTOR)] vt_variant_wrap_vec vt_variant_wrap_vec; + [case(VT_VARIANT | VT_ARRAY)] vt_variant_wrap_safearray vt_variant_wrap_array; + } variant_types; + + typedef [public] struct { + uint16 vtype; + uint8 vdata1; + uint8 vdata2; + [switch_is(vtype)] variant_types vvalue; + } wsp_cbasestoragevariant; + + typedef [public, nodiscriminant, switch_type(uint32)] union { + [case(DBKIND_GUID_NAME)] string vstring; + [default]; + } wsp_cdbcolid_opt_name; + + typedef [public] struct { + uint32 ekind; + [flag(NDR_ALIGN8)] DATA_BLOB _pad1; + GUID guid; + uint32 uiid; + [switch_is(ekind)] wsp_cdbcolid_opt_name vstring; + } wsp_cdbcolid; + + + typedef [public] struct { + uint32 msg; + uint32 status; + uint32 checksum; + uint32 ulreserved2; + } wsp_header; + + typedef [public,flag(NDR_ALIGN4)] struct { + uint32 dbpropid; + uint32 dbpropoptions; + uint32 dbpropstatus; + wsp_cdbcolid colid; + wsp_cbasestoragevariant vvalue; + } wsp_cdbprop; + + typedef [flag(NDR_NOALIGN),public] struct { + GUID guidpropertyset; + [flag(NDR_ALIGN4)] DATA_BLOB _pad1; + uint32 cproperties; + wsp_cdbprop aprops[cproperties]; + } wsp_cdbpropset; + + typedef [public] struct { + uint32 pidcolimn; + uint32 dworder; + uint32 dwindividual; + uint32 locale; + } wsp_csort; + + typedef [public] struct { + /* !! weirdly 8 bytes seems to be junk or unknown here. */ + uint32 unknown1; + uint32 unknown2; + uint32 count; + wsp_csort sortarray[count]; + } wsp_csortset; + + typedef [public] struct { + uint32 cpropsets; + wsp_cdbpropset propertyset1; + wsp_cdbpropset propertyset2; + } connectin_propsets; + + typedef [public] struct { + uint32 cextpropset; + wsp_cdbpropset apropertysets[cextpropset]; + } connectin_extpropsets; + + typedef [public] struct { + uint32 iclientversion; + uint32 fclientisremote; + uint32 cbblob1; + uint32 paddingcbblob2; + uint32 cbblob2; + uint8 padding[12]; + [flag(STR_NULLTERM)] string machinename; + [flag(STR_NULLTERM)] string username; + [flag(NDR_ALIGN8)] DATA_BLOB _pad1; + uint8 propsets[cbblob1]; + [flag(NDR_ALIGN8)] DATA_BLOB _pad2; + uint8 extpropsets[cbblob2]; + } wsp_cpmconnectin; + + typedef [public] struct { + uint32 reserved; + uint32 dwwinvermajor; + uint32 dwwinverminor; + uint32 dwnlsvermajor; + uint32 dwnlsverminor; + } version_info; + + typedef [public, nodiscriminant, switch_type(uint32)] union { + [case(WINDOWS_7)] version_info version_info; + [case(WINDOWS_2008)] version_info version_info; + [default] uint32 reserved[4]; + } version_dependant; + + typedef [public] struct { + uint32 server_version; + [switch_is(server_version)] version_dependant version_dependant; + } wsp_cpmconnectout; + + typedef [public] struct { + uint32 count; + uint32 indexes[count]; + } wsp_ccolumnset; + + + typedef [public] struct { + uint32 cnode; + wsp_crestriction panode[cnode]; + } wsp_cnoderestriction; + + typedef [public] struct { + uint32 len; + [charset(UTF16)] uint8 vstring[len*2]; + } wsp_len_string_pair; + + typedef [public, nodiscriminant, switch_type(uint32)] union { + [case(PRSPEC_LPWSTR)] wsp_len_string_pair propname; + [case(PRSPEC_PROPID)] uint32 prspec; + } wsp_propname_or_propid; + + typedef [public] struct { + uint32 cclabel; + [charset(UTF16)] uint8 vstring[cclabel*2]; + } wsp_labeldata; + + typedef [public, nodiscriminant, switch_type(uint8)] union { + [case(0)]; + [case(1)] wsp_labeldata data; + } opt_labeldata; + + typedef [public] struct { + uint32 ultype; + wsp_cbasestoragevariant prval; + uint8 labelpresent; + [switch_is(labelpresent)] opt_labeldata opt_data; + } wsp_rangeboundary; + + typedef [public] struct { + uint32 lcid; + uint32 crange; + wsp_rangeboundary arangebegin[crange + 1]; + } wsp_crangecategspec; + + typedef [public] struct { + uint32 ulcategtype; + wsp_csort sortkey; + wsp_crangecategspec crangecategspec; + } wsp_ccategspec; + + typedef [public] struct { + uint32 ulmaxnumtoret; + uint32 idrepresentitive; + } wsp_repofdata; + + typedef [public,nodiscriminant,switch_type(uint8)] union { + [case(DBAGGTTYPE_FIRST)] uint32 firstmaxnumret; + [case(DBAGGTTYPE_BYFREQ)] uint32 firstbyfreq; + [case(DBAGGTTYPE_REPRESENTATIVEOF)] wsp_repofdata repofdata; + [default]; + } opt_type_data; + + typedef [public] struct { + uint8 type; + [flag(NDR_ALIGN4)] DATA_BLOB _pad1; + uint32 ccalias; + [charset(UTF16)] uint8 alias[ccalias*2]; + uint32 idcolumn; + [switch_is(type)] opt_type_data opt_data; + } wsp_caggregspec; + + typedef [public] struct { + uint32 ccount; + wsp_caggregspec aggregspecs[ccount]; + } wsp_caggregset; + + typedef [public] struct { + uint32 order; + wsp_caggregspec columnspec; + } wsp_caggregsortkey; + + typedef [public] struct { + uint32 ccount; + wsp_caggregsortkey sortkeys[ccount]; + } wsp_csortaggregset; + + typedef [public] struct { + uint8 type; + [flag(NDR_ALIGN4)] DATA_BLOB _pad1; + wsp_cbasestoragevariant ingroupid; + wsp_csortaggregset sortaggregset; + } wsp_cingroupsortaggregset; + + typedef [public] struct { + uint32 ccount; + wsp_cingroupsortaggregset sortsets[ccount]; + } wsp_cingroupsortaggregsets; + + typedef [public] struct { + wsp_ccolumnset cscolumns; + wsp_ccategspec spec; + wsp_caggregset aggregset; + wsp_csortaggregset sortaggregset; + wsp_cingroupsortaggregsets ingroupsortaggset; + uint32 cmaxresults; + } wsp_ccategorizationspec; + + typedef [public] struct { + uint32 size; + wsp_ccategorizationspec categories[size]; + } wsp_ccategorizationset; + + typedef [flag(NDR_NOALIGN),public] struct { + [flag(NDR_ALIGN8)] DATA_BLOB _pad1; + GUID guidpropset; + uint32 ulkind; + [switch_is(ulkind)] wsp_propname_or_propid name_or_id; + } wsp_cfullpropspec; + + typedef [public] struct { + wsp_cfullpropspec property; + [flag(NDR_ALIGN4)] DATA_BLOB _pad1; + uint32 cc; + [charset(UTF16)] uint8 pwcsphrase[cc*2]; + [flag(NDR_ALIGN4)] DATA_BLOB _pad2; + uint32 lcid; + uint32 ulgeneratemethod; + } wsp_ccontentrestriction; + + typedef [public] struct { + uint32 relop; + wsp_cfullpropspec property; + wsp_cbasestoragevariant prval; + [flag(NDR_ALIGN4)] DATA_BLOB _pad1; + uint32 lcid; + } wsp_cpropertyrestriction; + + typedef [public] struct { + wsp_cfullpropspec property; + [flag(NDR_ALIGN4)] DATA_BLOB _pad1; + uint32 cc; + [charset(UTF16)] uint8 pwcsphrase[cc*2]; + [flag(NDR_ALIGN4)] DATA_BLOB _pad2; + uint32 lcid; + } wsp_cnatlanguagerestriction; + + /* #FIXME circumvent 'incomplete type' error in gen code */ + typedef [public] struct { + wsp_crestriction restriction[SINGLE_ITEM]; + } wsp_wrap_crestriction; + + typedef [public] struct { + /* no IEEE 754 implementation for float ?? */ + /* float ffvalue; */ + uint32 ffvalue; + wsp_crestriction childres[SINGLE_ITEM]; + } wsp_ccoercionrestriction; + + typedef [public] struct { + uint32 pres; + [flag(NDR_ALIGN4)] DATA_BLOB padding; + uint32 uirankmethod; + } wsp_cvectorrestriction; + + typedef [public] struct { + uint32 cclowerpath; + [charset(UTF16)] uint8 lowerpath[cclowerpath*2]; + [flag(NDR_ALIGN4)] DATA_BLOB padding; + uint32 length; + uint32 frecursive; + uint32 fvirtual; + } wsp_cscoperestriction; + + typedef [public] struct { + uint32 whereid; + } wsp_creusewhere; + + typedef [public] struct { + uint32 relop; + uint32 pid; + wsp_cbasestoragevariant prval; + uint32 lcid; + uint8 restrictionpresent; + wsp_crestriction nextrestriction[SINGLE_ITEM]; + } wsp_cinternalpropertyrestriction; + + typedef [public] struct { + wsp_cfullpropspec property; + uint32 fik1; + uint32 fik2; + uint32 fik3; + uint32 flb; + uint32 cfeedbackdoc; + uint32 probquerypid; + } wsp_cprobrestriction; + + typedef [public] struct { + uint32 feedbackdoc; + wsp_cfullpropspec property; + } wsp_cfeedbackrestriction; + + typedef [public] struct { + wsp_cbasestoragevariant vdocument; + } wsp_creldocrestriction; + + typedef [public,nodiscriminant,switch_type(uint32)] union { + [case(RTNONE)]; + [case(RTNOT)] wsp_wrap_crestriction restriction; + // without pidl patches uncomment line below to hang pidl + [case(RTAND)] wsp_cnoderestriction cnoderestriction; + [case(RTOR)] wsp_cnoderestriction orcnoderestriction; + [case(RTCONTENT)] wsp_ccontentrestriction ccontentrestriction; + [case(RTPROPERTY)] wsp_cpropertyrestriction cpropertyrestriction; + [case(RTPROXIMITY)] wsp_cnoderestriction proximityrestriction; + [case(RTVECTOR)] wsp_cvectorrestriction vectorrestriction; + [case(RTNATLANGUAGE)] wsp_cnatlanguagerestriction cnatlanguagerestriction; + [case(RTSCOPE)] wsp_cscoperestriction scoperestriction; + [case(RTREUSEWHERE)] wsp_creusewhere reusewhere; + [case(RTINTERNALPROP)] wsp_cinternalpropertyrestriction internalpropertyrestriction; + [case(RTPHRASE)] wsp_cnoderestriction phraserestriction; + [case(RTCOERCE_ABSOLUTE)] wsp_ccoercionrestriction ccoercionrestriction_abs; + [case(RTCOERCE_ADD)] wsp_ccoercionrestriction ccoercionrestriction_add; + [case(RTCOERCE_MULTIPLY)] wsp_ccoercionrestriction ccoercionrestriction_mul; + [case(RTPROB)] wsp_cprobrestriction probrestriction; + [case(RTFEEDBACK)] wsp_cfeedbackrestriction feedbackrestriction; + [case(RTRELDOC)] wsp_creldocrestriction reldocrestriction; + + } wsp_crestrictions; + + typedef [public] struct { + uint32 ultype; + uint32 weight; + [switch_is(ultype)] wsp_crestrictions restriction; + } wsp_crestriction; + + typedef [flag(NDR_NOALIGN),public] struct { + uint8 count; + uint8 ispresent; + [flag(NDR_ALIGN4)] DATA_BLOB _pad1; + wsp_crestriction restrictions[count]; + } wsp_crestrictionarray; + + + typedef [public] struct { + uint32 ubooleanoptions; + uint32 ulmaxopenrows; + uint32 ulmemoryusage; + uint32 cmaxresults; + uint32 ccmdtimeout; + } wsp_crowsetproperties; + + typedef [public] struct { + uint32 count; + [flag(NDR_ALIGN4)] DATA_BLOB _pad2; + wsp_cfullpropspec apropspec[count]; + } wsp_cpidmapper; + + typedef [public] struct { + uint32 pid; + uint32 weight; + } wsp_sproperty; + + typedef [public] struct { + uint32 count; + uint32 grouppid; + wsp_sproperty props[count]; + } wsp_ccolumngroup; + + typedef [public] struct { + uint32 count; + wsp_ccolumngroup agrouparray[count]; + } wsp_ccolumngrouparray; + + typedef [public,nodiscriminant,switch_type(uint8)] union { + [case(0)]; + [default] wsp_csortset sortset; + }opt_wsp_csortset; + + typedef [public,nodiscriminant,switch_type(uint8)] union { + [case(0)]; + [default] wsp_crestrictionarray restrictionarray; + }opt_wsp_crestrictionarray; + + typedef [public,nodiscriminant,switch_type(uint8)] union { + [case(0)]; + [default] wsp_ccolumnset columnset; + }opt_wsp_ccolumnset; + + typedef [public,nodiscriminant,switch_type(uint8)] union { + [case(0)]; + [default] wsp_ccategorizationset ccategorizationset; + }opt_wsp_ccategorizationset; + + typedef [public] struct { + uint32 size; + uint8 ccolumnsetpresent; + /* at the moment it seems padding is not needed here (and below) + * as structures seems to be default aligned to 4 byte + * boundries, perhaps we need to define all structures as + * non-aligned and do all aligning manually? however for + * the moment lets see how it works out leaving defaults in + * place + */ + /*[flag(NDR_ALIGN4)] DATA_BLOB _pad1;*/ + [switch_is(ccolumnsetpresent)] opt_wsp_ccolumnset columnset; + uint8 crestrictionpresent; + [switch_is(crestrictionpresent)] opt_wsp_crestrictionarray restrictionarray; + uint8 csortsetpresent; + /*[flag(NDR_ALIGN4)] DATA_BLOB _pad2;*/ + [switch_is(csortsetpresent)] opt_wsp_csortset sortset; + uint8 ccategorizationsetpresent; + /*[flag(NDR_ALIGN4)] DATA_BLOB _pad3;*/ + [switch_is(ccategorizationsetpresent)] opt_wsp_ccategorizationset ccategorizationset; + wsp_crowsetproperties rowsetproperties; + wsp_cpidmapper pidmapper; + wsp_ccolumngrouparray grouparray; + uint32 lcid; + } wsp_cpmcreatequeryin; + + typedef [public] struct { + uint32 ftruesequential; + uint32 fWorkIdUnique; + /* + * uint32 acursors[SIZE]; + * + * after fWorkIdUnique is an array of uint32 cursors, + * actually there is always at least 1 item in the array, + * SIZE is determined by the optional ccategorizationset field in + * the request + */ + } wsp_cpmcreatequeryout; + + typedef [public, nodiscriminant, switch_type(uint8)] union { + [case(1)] uint8 value; + [case(0)]; + } aggregatetype; + + typedef [public, nodiscriminant, switch_type(uint8)] union { + [case(1)] uint16 value; + [case(0)]; + } valueoffset; + + typedef [public, nodiscriminant, switch_type(uint8)] union { + [case(1)] uint16 value; + [case(0)]; + } valuesize; + + typedef [public, nodiscriminant, switch_type(uint8)] union { + [case(1)] uint16 value; + [case(0)]; + } lengthoffset; + + typedef [public, nodiscriminant, switch_type(uint8)] union { + [case(1)] uint16 value; + [case(0)]; + } statusoffset; + + typedef [public] struct { + wsp_cfullpropspec propspec; + uint32 vtype; + uint8 aggregateused; + [switch_is(aggregateused)] aggregatetype aggregatetype; + uint8 valueused; + [switch_is(valueused)] valueoffset valueoffset; /* auto aligned to 2 byte boundry */ + [switch_is(valueused)] valuesize valuesize; /* auto aligned to 2 byte boundry */ + uint8 statusused; + [switch_is(statusused)] statusoffset statusoffset; /* auto aligned to 2 byte boundry */ + uint8 lengthused; + [switch_is(lengthused)] lengthoffset lengthoffset; /* auto aligned to 2 byte boundry */ + } wsp_ctablecolumn; + + /* can't see where the struct below is referenced */ + typedef [public] struct { + uint32 type; + uint32 lcid; + uint32 ccomplstrings; + wsp_serializedpropertyvalue apszcomplstrings[ccomplstrings]; + uint32 ccomplpids; + uint32 acomplpids[ccomplpids]; + } wsp_ccompletioncategspec; + + typedef [public] struct { + uint32 hcursor; + uint32 brow; + uint32 bbindingdesc; + uint32 dummy; + uint32 ccolumns; + wsp_ctablecolumn acolumns[ccolumns]; + } wsp_cpmsetbindingsin; + + typedef [public] struct { + uint32 cskip; + } wsp_crowseeknext; + + typedef [public] struct { + uint32 bmkoffset; + uint32 cskip; + uint32 hregion; + } wsp_crowseekat; + + typedef [public] struct { + uint32 ulnumerator; + uint32 uldenominator; + uint32 hregion; + } wsp_crowseekatratio; + + typedef [public] struct { + uint32 cbookmarks; + uint32 abookmarks[cbookmarks]; + uint32 maxret; + uint32 ascret[maxret]; + } wsp_crowseekbybookmark; + + typedef [public,nodiscriminant,switch_type(uint32)] union { + [case(EROWSEEKNONE)]; + [case(EROWSEEKNEXT)] wsp_crowseeknext crowseeknext; + [case(EROWSEEKAT)] wsp_crowseekat crowseekat; + [case(EROWSEEKATRATIO)] wsp_crowseekatratio crowseekatratio; + [case(EROWSEEKBYBOOKMARK)] wsp_crowseekbybookmark crowseekbybookmark; + } wsp_seekdescription; + + typedef [public] struct { + uint32 hcursor; + uint32 crowstotransfer; + uint32 cbrowWidth; + uint32 cbseek; + uint32 cbreserved; + uint32 cbreadbuffer; + uint32 ulclientbase; + uint32 fbwdfetch; + uint32 etype; + uint32 chapt; + [switch_is(etype)] wsp_seekdescription seekdescription; + } wsp_cpmgetrowsin; + + typedef [public] struct { + uint16 vtype; + uint16 reserved1; + uint32 reserved2; + uint32 offset; + } wsp_crowvariant32; + + typedef [public] struct { + uint32 rowsreturned; + uint32 etype; + uint32 chapt; + [switch_is(etype)] wsp_seekdescription seekdescription; + /* + * following rows data is not defined here, size is unknown + * in the context of this structure but is the size of cbreadbuffer + * defined in cpmgetrowsin. + */ + } wsp_cpmgetrowsout; + + typedef [public] struct { + uint32 hcursor; + } wsp_cpmfreecursorin; + + typedef [public] struct { + uint32 ccursorsremaining; + } wsp_cpmfreecursorout; + + typedef [public] struct { + uint32 hcursor; + } wsp_cpmgetquerystatusin; + + typedef [public] struct { + uint32 qstatus; + } wsp_cpmgetquerystatusout; + + typedef [public] struct { + uint32 hcursor; + uint32 bmk; + } wsp_cpmgetquerystatusexin; + + typedef [public] struct { + uint32 qstatus; + uint32 cfiltereddocuments; + uint32 cdocumentstofilter; + uint32 dwratiofinisheddenominator; + uint32 dwratiofinishednumerator; + uint32 irowbmk; + uint32 crowstotal; + uint32 maxrank; + uint32 resultsfound; + uint32 whereid; + } wsp_cpmgetquerystatusexout; + + typedef [public] struct { + uint32 hcursor; + uint32 chapter; + } wsp_cpmrestartpositionin; + + typedef [public] struct { + uint32 hcursor; + uint32 fquick; + } wsp_cpmratiofinishedin; + + typedef [public] struct { + uint32 ulnumerator; + uint32 uldenominator; + uint32 crows; + uint32 fnewrows; + } wsp_cpmratiofinishedout; + + typedef [public] struct { + uint32 wid; + uint32 cbsofar; + uint32 cbpropspec; + uint32 cbchunk; + wsp_cfullpropspec propspec; + } wsp_cpmfetchvaluein; + + typedef [public] struct { + uint16 cdims; + safearraybound rgsabound[cdims]; + int8 vdata[calc_array_size(rgsabound, cdims)]; + } vt_i1_safe2_array; + + typedef [public] struct { + uint16 cdims; + safearraybound rgsabound[cdims]; + uint8 vdata[calc_array_size(rgsabound, cdims)]; + } vt_ui1_safe2_array; + + typedef [public] struct { + uint16 cdims; + safearraybound rgsabound[cdims]; + int16 vdata[calc_array_size(rgsabound, cdims)]; + } vt_i2_safe2_array; + + typedef [public] struct { + uint16 cdims; + safearraybound rgsabound[cdims]; + uint16 vdata[calc_array_size(rgsabound, cdims)]; + } vt_ui2_safe2_array; + + typedef [public] struct { + uint16 cdims; + safearraybound rgsabound[cdims]; + int32 vdata[calc_array_size(rgsabound, cdims)]; + } vt_i4_safe2_array; + + typedef [public] struct { + uint16 cdims; + safearraybound rgsabound[cdims]; + uint32 vdata[calc_array_size(rgsabound, cdims)]; + } vt_ui4_safe2_array; + + typedef [public] struct { + uint16 cdims; + safearraybound rgsabound[cdims]; + wsp_hyper vdata[calc_array_size(rgsabound, cdims)]; + } vt_wsp_hyper_safe2_array; + + typedef [public] struct { + uint16 cdims; + safearraybound rgsabound[cdims]; + vt_bstr vdata[calc_array_size(rgsabound, cdims)]; + } vt_bstr_safe2_array; + + typedef [public] struct { + uint16 cdims; + safearraybound rgsabound[cdims]; + vt_variant_wrap vdata[calc_array_size(rgsabound, cdims)]; + } vt_variant_wrap_safearray2; + + typedef [public,nodiscriminant,switch_type(uint32)] union { + [case(VT_I1)] int8 vt_i1; + [case(VT_I1 | VT_ARRAY)] vt_i1_safe2_array vt_i1_array; + [case(VT_I1 | VT_VECTOR)] vt_i1_vec vt_i1_vec; + + [case(VT_UI1)] uint8 vt_ui1; + [case(VT_UI1 | VT_ARRAY)] vt_ui1_safe2_array vt_ui1_array; + [case(VT_UI1 | VT_VECTOR)] vt_ui1_vec vt_ui1_vec; + + [case(VT_I2)] int16 vt_i2; + [case(VT_I2 | VT_ARRAY)] vt_i2_safe2_array vt_i2_array; + [case(VT_I2 | VT_VECTOR)] vt_i2_vec vt_i2_vec; + + [case(VT_UI2)] uint16 vt_ui2; + [case(VT_UI2 | VT_ARRAY)] vt_ui2_safe2_array vt_ui2_array; + [case(VT_UI2 | VT_VECTOR)] vt_ui2_vec vt_ui2_vec; + + [case(VT_BOOL)] uint16 vt_bool; + [case(VT_BOOL | VT_ARRAY)] vt_ui2_safe2_array vt_bool_array; + [case(VT_BOOL | VT_VECTOR)] vt_ui2_vec vt_bool_vec; + + [case(VT_I4)] int32 vt_i4; + [case(VT_I4 | VT_VECTOR)] vt_i4_vec vt_i4_vec; + [case(VT_I4 | VT_ARRAY)] vt_i4_safe2_array vt_i4_array; + + [case(VT_UI4)] uint32 vt_ui4; + [case(VT_UI4 | VT_VECTOR)] vt_ui4_vec vt_ui4_vec; + [case(VT_UI4 | VT_ARRAY)] vt_ui4_safe2_array vt_ui4_array; + + [case(VT_R4)] uint32 vt_r4; + [case(VT_R4 | VT_VECTOR)] vt_i4_vec vt_r4_vec; + [case(VT_R4 | VT_ARRAY)] vt_i4_safe2_array vt_r4_array; + + [case(VT_INT)] int32 vt_int; + [case(VT_INT | VT_ARRAY)] vt_i4_safe2_array vt_int_array; + + [case(VT_UINT)] uint32 vt_uint; + [case(VT_UINT | VT_ARRAY)] vt_ui4_safe2_array vt_uint_array; + + [case(VT_ERROR)] uint32 vt_error; + [case(VT_ERROR | VT_VECTOR)] vt_ui4_vec vt_error_vec; + [case(VT_ERROR | VT_ARRAY)] vt_ui4_safe2_array vt_error_array; + + [case(VT_I8)] wsp_hyper vt_i8; + [case(VT_I8 | VT_VECTOR)] vt_wsp_hyper_vec vt_i8_vec; + + [case(VT_UI8)] wsp_hyper vt_ui8; + [case(VT_UI8 | VT_VECTOR)] vt_wsp_hyper_vec vt_ui8_vec; + + [case(VT_R8)] wsp_hyper vt_r8; + [case(VT_R8 | VT_VECTOR)] vt_wsp_hyper_vec vt_r8_vec; + [case(VT_R8 | VT_ARRAY)] vt_wsp_hyper_safe2_array vt_r8_array; + + [case(VT_CY)] wsp_hyper vt_cy; + [case(VT_CY | VT_VECTOR)] vt_wsp_hyper_vec vt_cy_vec; + [case(VT_CY | VT_ARRAY)] vt_wsp_hyper_safe2_array vt_cy_array; + + [case(VT_DATE)] wsp_hyper vt_date; + [case(VT_DATE | VT_VECTOR)] vt_wsp_hyper_vec vt_date_vec; + [case(VT_DATE| VT_ARRAY)] vt_wsp_hyper_safe2_array vt_date_array; + + [case(VT_FILETIME)] wsp_hyper vt_filetime; + [case(VT_FILETIME | VT_VECTOR)] vt_wsp_hyper_vec vt_filetime_vec; + + [case(VT_BSTR)] vt_bstr vt_bstr; + [case(VT_BSTR | VT_VECTOR)] vt_bstr_vec vt_bstr_v; + [case(VT_BSTR | VT_ARRAY)] vt_bstr_safe2_array vt_bstr_array; + + [case(VT_LPWSTR)] vt_lpwstr vt_lpwstr; + [case(VT_LPWSTR | VT_VECTOR)] vt_lpwstr_vec vt_lpwstr_v; + + [case(VT_COMPRESSED_LPWSTR)] vt_compressed_lpwstr vt_compressed_lpwstr; + [case(VT_COMPRESSED_LPWSTR | VT_VECTOR)] vt_compressed_lpwstr_vec vt_compresseed_lpwstr_v; + + [case(VT_DECIMAL)] vt_decimal vt_decimal; + [case(VT_DECIMAL | VT_VECTOR)] vt_decimal_vec vt_decimal_v; + + [case(VT_CLSID)] GUID vt_clid; + [case(VT_CLSID | VT_VECTOR)] vt_clsid_vec vt_clsid_v; + + [case(VT_BLOB)] DATA_BLOB vt_blob; + [case(VT_BLOB_OBJECT)] DATA_BLOB vt_blob_object; + + [case(VT_NULL)]; + [case(VT_EMPTY)]; + + [case(VT_VARIANT)] vt_variant_wrap vt_variant_wrap; + [case(VT_VARIANT | VT_VECTOR)] vt_variant_wrap_vec vt_variant_wrap_vec; + [case(VT_VARIANT | VT_ARRAY)] vt_variant_wrap_safearray2 vt_variant_wrap_array; + } serialised_types; + + typedef [public] struct { + uint32 dwtype; + [switch_is(dwtype)] serialised_types rgb; + } wsp_serializedpropertyvalue; + + typedef [public] struct { + uint32 cbvalue; + uint32 fmoreexists; + uint32 fvalueexists; + /* + * very nearly the same as wsp_cbasestoragevariant, only + * different in how array types are represented, also only + * a portion of the value (serializedpropertyvalue) is here + */ + uint8 value[cbvalue]; + } wsp_cpmfetchvalueout; + + typedef [public] struct { + uint32 priority; + uint32 eventfrequency; + } wsp_cpmsetscopeprioritizationin; + + typedef [public] struct { + uint32 watchnotify; + } wsp_cpmsendnotifyout; + + typedef [public] struct { + uint32 wid; + uint8 eventinfo; + uint8 rowitemstate; + uint8 changeditemstate; + uint8 rowsetevent; + wsp_hyper rowseteventdata1; + wsp_hyper rowseteventdata2; + } wsp_cpmgetrowsetnotifyout; + + typedef [public] struct { + uint32 dwindexeditems; + uint32 dwoutstandingadds; + uint32 dwoustandingmodifies; + } wsp_cpmgetscopestatisticsout; + + typedef [public] struct { + uint32 hcursor; + uint32 chapt; + uint32 bmk; + } wsp_cpmgetapproximatepositionin; + + typedef [public] struct { + uint32 numerator; + uint32 denominator; + } wsp_cpmgetapproximatepositionout; + + typedef [public] struct { + uint32 hcursor; + uint32 chapt; + uint32 bmkfirst; + uint32 bmksecond; + } wsp_cpmcomparebmkin; + + typedef [public] struct { + uint32 dwcomparison; + } wsp_cpmcomparebmkout; + + + typedef [public] struct { + uint32 cbstruct; + uint32 cwordlist; + uint32 cpersistentindex; + uint32 cqueries; + uint32 cdocuments; + uint32 cfreshtest; + uint32 dwmergeprogress; + uint32 estate; + uint32 cfiltereddocuments; + uint32 ctotaldocuments; + uint32 cpendingscans; + uint32 dwindexsize; + uint32 cuniquekeys; + uint32 csecqdocuments; + uint32 dwpropcachesize; + } wsp_cpmcistateinout; + + typedef [public] struct { + uint32 cwids; + uint32 cdepthprev; + uint32 pwids[cwids]; + uint32 prgirowprev[cdepthprev]; + } wsp_findindicesin; + + typedef [public] struct { + uint32 cdepthnext; + uint32 prgirownext[cdepthnext]; + } wsp_findindicesout; + + typedef [public] struct { + uint32 hcursor; + uint32 chapt; + } wsp_cpmsresetstartpos; + + typedef [public, nodiscriminant, switch_type(uint32)] union { + [case(CPMCONNECT)] wsp_cpmconnectin cpmconnect; + [case(CPMCREATEQUERY)] wsp_cpmcreatequeryin cpmcreatequery; + [case(CPMFREECURSOR)] wsp_cpmfreecursorin cpmfreecursor; + [case(CPMGETROWS)] wsp_cpmgetrowsin cpmgetrows; + [case(CPMSETBINDINGSIN)] wsp_cpmsetbindingsin cpmsetbindings; + [case(CPMRESTARTPOSITIONIN)] wsp_cpmsresetstartpos cpmresetstartpos; + [case(CPMGETQUERYSTATUS)] wsp_cpmgetquerystatusin cpmgetquerystatus; + [case(CPMGETQUERYSTATUSEX)] wsp_cpmgetquerystatusexin cpmgetquerystatusex; + [case(CPMSETSCOPEPRIORITIZATION)] wsp_cpmsetscopeprioritizationin cpmsetscopeprioritizationin; + [case(CPMGETNOTIFY)]; /*header only*/ + [case(CPMGETROWSETNOTIFY)]; /*header only*/ + [case(CPMDISCONNECT)]; /*header only*/ + [case(CPMGETSCOPESTATISTICS)]; /*header only*/ + [case(CPMGETAPPROXIMATEPOSITION)] wsp_cpmgetapproximatepositionin getapproximateposition; + [case(CPMCOMPAREBMK)] wsp_cpmcomparebmkin cpmcomparebmk; + [case(CPMCISTATEOUT)] wsp_cpmcistateinout wsp_cpmcistate; + [case(CPMFINDINDICES)] wsp_findindicesin wsp_findindices; + [case(CPMRATIOFINISHED)] wsp_cpmratiofinishedin wsp_cpmratiofinished; + } req_message; + + typedef [public, nodiscriminant, switch_type(uint32)] union { + [case(CPMCONNECT)] wsp_cpmconnectout cpmconnect; + [case(CPMCREATEQUERY)] wsp_cpmcreatequeryout cpmcreatequery; + [case(CPMFREECURSOR)] wsp_cpmfreecursorout cpmfreecursor; + [case(CPMGETROWS)] wsp_cpmgetrowsout cpmgetrows; + [case(CPMSETBINDINGSIN)]; /* just has header */ + [case(CPMRESTARTPOSITIONIN)]; /* just has header */ + [case(CPMGETQUERYSTATUS)] wsp_cpmgetquerystatusout cpmgetquerystatus; + [case(CPMSENDNOTIFYOUT)] wsp_cpmsendnotifyout cpmsendnotifyoutcpmgetquerystatus; + [case(CPMGETQUERYSTATUSEX)] wsp_cpmgetquerystatusexout cpmgetquerystatusex; + [case(CPMSETSCOPEPRIORITIZATION)]; /* just had header */ + [case(CPMGETROWSETNOTIFY)] wsp_cpmgetrowsetnotifyout cpmgetrowsetnotifyout; + [case(CPMGETAPPROXIMATEPOSITION)] wsp_cpmgetapproximatepositionout getapproximateposition; + [case(CPMCOMPAREBMK)] wsp_cpmcomparebmkout cpmcomparebmk; + [case(CPMCISTATEOUT)] wsp_cpmcistateinout wsp_cpmcistate; + [case(CPMFINDINDICES)] wsp_findindicesout wsp_findindices; + [case(CPMGETSCOPESTATISTICS)] wsp_cpmgetscopestatisticsout cpmgetscopestatistics; + [case(CPMRATIOFINISHED)] wsp_cpmratiofinishedout wsp_cpmratiofinished; + } resp_message; + + typedef [public] struct { + wsp_header header; + [switch_is(header.msg)] req_message message; + } wsp_request; + + typedef [public] struct { + wsp_header header; + [switch_is(header.msg)] resp_message message; + } wsp_response; + +}; + diff --git a/librpc/idl/wsp_data.idl b/librpc/idl/wsp_data.idl new file mode 100644 index 0000000..4fa175f --- /dev/null +++ b/librpc/idl/wsp_data.idl @@ -0,0 +1,301 @@ +#include "idl_types.h" +[ + pointer_default(unique) +] + +interface constants +{ + /* values for guidPropertySet */ + const char* DBPROPSET_FSCIFRMWRK_EXT = "A9BD1526-6A80-11D0-8C9D-0020AF1D740E"; + const char* DBPROPSET_QUERYEXT = "A7AC77ED-F8D7-11CE-A798-0020F8008025"; + const char* DBPROPSET_CIFRMWRKCORE_EXT = "AFAFACA5-B5D1-11D0-8C62-00C04FC2DB8D"; + const char* DBPROPSET_MSIDXS_ROWSETEXT = "AA6EE6B0-E828-11D0-B23E-00AA0047FC01"; + + /* Chapter and bookmark handle well known values */ + const uint32_t DB_NULL_HCHAPTER = 0x00000000; + const uint32_t DBBMK_FIRST = 0xFFFFFFFC; + const uint32_t DBBMK_LAST = 0xFFFFFFFD; + /* properties of DBPROPSET_FSCIFRMWRK_EXT propertyset */ + const uint32_t DBPROP_CI_CATALOG_NAME = 0x00000002; + const uint32_t DBPROP_CI_INCLUDE_SCOPES = 0x00000003; + const uint32_t DBPROP_CI_SCOPE_FLAGS = 0x00000004; + const uint32_t DBPROP_CI_QUERY_TYPE = 0x00000007; + const uint32_t DBPROP_GENERICOPTIONS_STRING = 0x00000006; + const uint32_t DBPROP_USECONTENTINDEX = 0x00000002; + const uint32_t DBPROP_IGNORENOISEONLYCLAUSES = 0x00000005; + const uint32_t DBPROP_DEFERCATALOGVERIFICATION = 0x00000008; + const uint32_t DBPROP_IGNORESBRI = 0x0000000E; + const uint32_t DBPROP_GENERATEPARSETREE = 0x0000000A; + const uint32_t DBPROP_FREETEXTANYTERM = 0x0000000C; + const uint32_t DBPROP_FREETEXTUSESTEMMING = 0x0000000D; + + /* properties of DBPROPSET_QUERYEXT propertyset */ + const uint32_t DBPROP_DEFERNONINDEXEDTRIMMING = 0x00000003; + const uint32_t DBPROP_USEEXTENDEDDBTYPES = 0x00000004; + const uint32_t DBPROP_FIRSTROWS = 0x00000007; + const uint32_t DBPROP_ENABLEROWSETEVENTS = 0x00000010; + + /* properties of DBPROPSET_MSIDXS_ROWSETEXT */ + + const uint32_t MSIDXSPROP_ROWSETQUERYSTATUS = 0x02; + const uint32_t MSIDXSPROP_COMMAND_LOCALE_STRING = 0x03; + const uint32_t MSIDXSPROP_QUERY_RESTRICTION = 0x04; + const uint32_t MSIDXSPROP_PARSE_TREE = 0x05; + const uint32_t MSIDXSPROP_MAX_RANK = 0x06; + const uint32_t MSIDXSPROP_RESULTS_FOUND = 0x07; + + /* flags of DBPROP_CI_SCOPE_FLAGS property */ + const uint32_t QUERY_DEEP = 0x01; + const uint32_t QUERY_VIRTUAL_PATH = 0x02; + + /* query type for BPROP_CI_QUERY_TYPE property */ + const uint32_t CINORMAL = 0x00000000; + + /* properties of DBPROPSET_CIFRMWRKCORE_EXT propertyset */ + + const uint32_t DBPROP_MACHINE = 0x00000002; + const uint32_t DBPROP_CLIENT_CLSID = 0x00000003; + + /* + * STAT bit constants + */ + + /* The asynchronous query is still running. */ + const uint32_t STAT_BUSY = 0x00000000; + /* The query is in an error state. */ + const uint32_t STAT_ERROR = 0x00000001; + /* The query is complete and rows can be requested. */ + const uint32_t STAT_DONE = 0x00000002; + /* The query is comp*/ + const uint32_t STAT_REFRESH = 0x00000003; + /* + * Noise words were replaced by wildcard characters in the + * content query. + */ + const uint32_t STAT_NOISE_WORDS = 0x00000010; + /* + * The results of the query might be incorrect because the + * query involved modified but unindexed files. + */ + const uint32_t STAT_CONTENT_OUT_OF_DATE = 0x00000020; + /* + * The content query was too complex to complete or + * required enumeration instead of use of the content index. + */ + const uint32_t STAT_CONTENT_QUERY_INCOMPLETE = 0x00000080; + /* + * The results of the query might be incorrect because the + * query execution reached the maximum allowable time. + */ + const uint32_t STAT_TIME_LIMIT_EXCEEDED = 0x00000100; + + /* + * a const to force an inline array to be evaluated at runtime to + * to get around an incomplete type error + */ + const uint32 SINGLE_ITEM = 1; + + /* WSP message types */ + + /* CPMConnectIn or CPMConnectOut */ + const uint32 CPMCONNECT = 0x000000C8; + /* CPMDisconnect */ + const uint32 CPMDISCONNECT = 0x000000C9; + /* CPMCreateQueryIn or CPMCreateQueryOut */ + const uint32 CPMCREATEQUERY = 0x000000CA; + /* CPMFreeCursorIn or CPMFreeCursorOut */ + const uint32 CPMFREECURSOR = 0x000000CB; + /* CPMGetRowsIn or CPMGetRowsOut */ + const uint32 CPMGETROWS = 0x000000CC; + /* CPMRatioFinishedIn or CPMRatioFinishedOut */ + const uint32 CPMRATIOFINISHED = 0x000000CD; + /* CPMCompareBmkIn or CPMCompareBmkOut */ + const uint32 CPMCOMPAREBMK = 0x000000CE; + /* CPMGetApproximatePositionIn or CPMGetApproximatePositionOut */ + const uint32 CPMGETAPPROXIMATEPOSITION = 0x000000CF; + /* CPMSetBindingsIn */ + const uint32 CPMSETBINDINGSIN = 0x000000D0; + /* CPMGetNotify */ + const uint32 CPMGETNOTIFY = 0x000000D1; + /* CPMSendNotifyOut */ + const uint32 CPMSENDNOTIFYOUT = 0x000000D2; + /* CPMGetQueryStatusIn or CPMGetQueryStatusOut */ + const uint32 CPMGETQUERYSTATUS = 0x000000D7; + /* CPMCiStateInOut */ + const uint32 CPMCISTATEOUT = 0x000000D9; + /* CPMFetchValueIn or CPMFetchValueOut */ + const uint32 CPMFETCHVALUE = 0x000000E4; + /* CPMGetQueryStatusExIn or CPMGetQueryStatusExOut */ + const uint32 CPMGETQUERYSTATUSEX = 0x000000E7; + /* CPMRestartPositionIn */ + const uint32 CPMRESTARTPOSITIONIN = 0x000000E8; + /* CPMSetCatStateIn (not supported) */ + const uint32 CPMSETCATSTATEIN = 0x000000EC; + /* CPMGetRowsetNotifyIn or CPMGetRowsetNotifyOut */ + const uint32 CPMGETROWSETNOTIFY = 0x000000F1; + /* CPMFindIndicesIn, or CPMFindIndicesOut */ + const uint32 CPMFINDINDICES = 0x000000F2; + /* CPMSetScopePrioritizationIn or CPMSetScopePrioritizationOut */ + const uint32 CPMSETSCOPEPRIORITIZATION = 0x000000F3; + /* CPMGetScopeStatisticsIn or CPMGetScopeStatisticsOut */ + const uint32 CPMGETSCOPESTATISTICS = 0x000000F4; + + const uint32 DBKIND_GUID_NAME = 0x00000000; + const uint32 DBKIND_GUID_PROPID = 0x00000001; + const uint32 PRSPEC_LPWSTR = 0x00000000; + const uint32 PRSPEC_PROPID = 0x00000001; + /* type constants for variant types */ + + const uint32 VT_EMPTY = 0x0000; + const uint32 VT_NULL = 0x0001; + const uint32 VT_I2 = 0x0002; + const uint32 VT_I4 = 0x0003; + const uint32 VT_R4 = 0x0004; + const uint32 VT_R8 = 0x0005; + const uint32 VT_CY = 0x0006; + const uint32 VT_DATE = 0x0007; + const uint32 VT_BSTR = 0x0008; + const uint32 VT_I1 = 0x0010; + const uint32 VT_UI1 = 0x0011; + const uint32 VT_UI2 = 0x0012; + const uint32 VT_UI4 = 0x0013; + const uint32 VT_I8 = 0x0014; + const uint32 VT_UI8 = 0x0015; + const uint32 VT_INT = 0x0016; + const uint32 VT_UINT = 0x0017; + const uint32 VT_ERROR = 0x000A; + const uint32 VT_BOOL = 0x000B; + const uint32 VT_VARIANT = 0x000C; + const uint32 VT_DECIMAL = 0x000E; + const uint32 VT_FILETIME = 0x0040; + const uint32 VT_BLOB = 0x0041; + const uint32 VT_BLOB_OBJECT = 0x0046; + const uint32 VT_CLSID = 0x0048; + const uint32 VT_LPSTR = 0x001E; + const uint32 VT_LPWSTR = 0x001F; + const uint32 VT_COMPRESSED_LPWSTR = 0x0023; + const uint32 VT_VECTOR = 0x1000; + const uint32 VT_ARRAY = 0x2000; + + /* restriction types */ + const uint32 RTNONE = 0x00000000; + const uint32 RTAND = 0x00000001; + const uint32 RTOR = 0x00000002; + const uint32 RTNOT = 0x00000003; + const uint32 RTCONTENT = 0x00000004; + const uint32 RTPROPERTY = 0x00000005; + const uint32 RTPROXIMITY = 0x00000006; + const uint32 RTVECTOR = 0x00000007; + const uint32 RTNATLANGUAGE = 0x00000008; + const uint32 RTSCOPE = 0x00000009; + const uint32 RTREUSEWHERE = 0x00000011; + const uint32 RTINTERNALPROP = 0x00FFFFFA; + const uint32 RTPHRASE = 0x00FFFFFD; + const uint32 RTCOERCE_ADD = 0x0000000A; + const uint32 RTCOERCE_MULTIPLY = 0x0000000B; + const uint32 RTCOERCE_ABSOLUTE = 0x0000000C; + const uint32 RTPROB = 0x0000000D; + const uint32 RTFEEDBACK = 0x0000000E; + const uint32 RTRELDOC = 0x0000000F; + + + /* Row seek types */ + const uint32 EROWSEEKNONE = 0x00000000; + const uint32 EROWSEEKNEXT = 0x00000001; + const uint32 EROWSEEKAT = 0x00000002; + const uint32 EROWSEEKATRATIO = 0x00000003; + const uint32 EROWSEEKBYBOOKMARK = 0x00000004; + + const uint32 WINDOWS_7 = 0x00000700; + const uint32 WINDOWS_2008 = 0x00010700; + + /* Relops */ + const uint32 PRLT = 0x00000000; + const uint32 PRLE = 0x00000001; + const uint32 PRGT = 0x00000002; + const uint32 PRGE = 0x00000003; + const uint32 PREQ = 0x00000004; + const uint32 PRNE = 0x00000005; + const uint32 PRRE = 0x00000006; + const uint32 PRALLBITS = 0x00000007; + const uint32 PRSOMEBITS = 0x00000008; + const uint32 PRALL = 0x00000100; + const uint32 PRANY = 0x00000200; + + const uint32 PROPAGATE_NONE = 0; + const uint32 PROPAGATE_ADD = 1; + const uint32 PROPAGATE_DELETE = 2; + const uint32 PROPAGATE_MODIFY = 3; + const uint32 PROPAGATE_ROWSET = 4; + + const uint32 ROWSETEVENT_ITEMSTATE_NOTINROWSET = 0; + const uint32 ROWSETEVENT_ITEMSTATE_INROWSET = 1; + const uint32 ROWSETEVENT_ITEMSTATE_UNKNOWN = 2; + + const uint32 ROWSETEVENT_TYPE_DATAEXPIRED = 0; + const uint32 ROWSETEVENT_TYPE_FOREGROUNDLOST = 1; + const uint32 ROWSETEVENT_TYPE_SCOPESTATISTICS = 2; + + const uint32 DBCOMPARE_LT = 0x00000000; + const uint32 DBCOMPARE_EQ = 0x00000001; + const uint32 DBCOMPARE_GT = 0x00000002; + const uint32 DBCOMPARE_NE = 0x00000003; + const uint32 DBCOMPARE_NOTCOMPARABLE = 0x00000004; + + const uint32 VECTOR_RANK_MIN = 0x00000000; + const uint32 VECTOR_RANK_MAX = 0x00000001; + const uint32 VECTOR_RANK_INNER = 0x00000002; + const uint32 VECTOR_RANK_DICE = 0x00000003; + const uint32 VECTOR_RANK_JACCARD = 0x00000004; + + const uint32 DBAGGTTYPE_BYNONE = 0x00000000; + const uint32 DBAGGTTYPE_SUM = 0x00000001; + const uint32 DBAGGTTYPE_MAX = 0x00000002; + const uint32 DBAGGTTYPE_MIN = 0x00000003; + const uint32 DBAGGTTYPE_AVG = 0x00000004; + const uint32 DBAGGTTYPE_COUNT = 0x00000005; + const uint32 DBAGGTTYPE_CHILDCOUNT = 0x00000006; + const uint32 DBAGGTTYPE_BYFREQ = 0x00000007; + const uint32 DBAGGTTYPE_FIRST = 0x00000008; + const uint32 DBAGGTTYPE_DATERANGE = 0x00000009; + const uint32 DBAGGTTYPE_REPRESENTATIVEOF= 0x0000000a; + const uint32 DBAGGTTYPE_EDITDISTANCE = 0x0000000b; + + const uint32 ESEQUENTIAL = 0x00000001; + const uint32 ELOCATEABLE = 0x00000003; + const uint32 ESCROLLABLE = 0x00000007; + const uint32 EASYNCHRONOUS = 0x00000008; + const uint32 EFIRSTROWS = 0x00000080; + const uint32 EHOLDROWS = 0x00000200; + const uint32 ECHAPTERED = 0x00000800; + const uint32 EUSECI = 0x00001000; + const uint32 EDEFERTRIMMING = 0x00002000; + const uint32 ENABLEROWSETEVENTS = 0x00800000; + const uint32 EDONOTCOMPUTEEXPENSIVEPROPS = 0x00400000; + + const uint32 CI_STATE_SHADOW_MERGE = 0x00000001; + const uint32 CI_STATE_MASTER_MERGE = 0x00000002; + const uint32 CI_STATE_ANNEALING_MERGE = 0x00000008; + const uint32 CI_STATE_SCANNING = 0x00000010; + const uint32 CI_STATE_LOW_MEMORY = 0x00000080; + const uint32 CI_STATE_HIGH_IO = 0x00000100; + const uint32 CI_STATE_MASTER_MERGE_PAUSED = 0x00000200; + const uint32 CI_STATE_READ_ONLY = 0x00000400; + const uint32 CI_STATE_BATTERY_POWER = 0x00000800; + const uint32 CI_STATE_USER_ACTIVE = 0x00001000; + const uint32 CI_STATE_LOW_DISK = 0x00010000; + const uint32 CI_STATE_HIGH_CPU = 0x00020000; + + const uint32 STORESTATUSOK = 0x00000000; + const uint32 STORESTATUSDEFERRED = 0x00000001; + const uint32 STORESTATUSNULL = 0x00000002; + + const uint32 DB_S_ENDOFROWSET = 0x00040EC6; + + const uint32 XOR_CONST = 0x59533959; + const uint32 E_UNEXPECTED = 0x8000FFFF; + const uint32 WIN_UPDATE_ERR = 0x80070003; + + const uint32 QUERY_SORTASCEND = 0x00000000; + const uint32 QUERY_DESCEND = 0x00000001; +} diff --git a/librpc/rpc/wsp_helper.c b/librpc/rpc/wsp_helper.c new file mode 100644 index 0000000..3d88a88 --- /dev/null +++ b/librpc/rpc/wsp_helper.c @@ -0,0 +1,52 @@ +/* + * Unix SMB/CIFS implementation. + * + * Window Search Service + * + * Copyright (c) 2016 Noel Power + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#include "includes.h" +#include "librpc/rpc/wsp_helper.h" +#include "bin/default/librpc/gen_ndr/ndr_wsp.h" + +void uint64_to_wsp_hyper(uint64_t src, struct wsp_hyper *dest) +{ + dest->hi = (uint32_t)src; + dest->lo = (uint32_t)(src>>32); +} + +void wsp_hyper_to_uint64(struct wsp_hyper *src, uint64_t *dest) +{ + *dest = src->lo; + *dest <<= 32; + *dest |= src->hi; +} + +uint32_t calc_array_size(struct safearraybound *bounds, uint32_t ndims) +{ + int i; + int result = 0; + + for(i = 0; i < ndims; i++) { + uint32_t celements = bounds[i].celements; + if (i) { + result = result * celements; + } else { + result = celements; + } + } + return result; +} diff --git a/librpc/rpc/wsp_helper.h b/librpc/rpc/wsp_helper.h new file mode 100644 index 0000000..76b5156 --- /dev/null +++ b/librpc/rpc/wsp_helper.h @@ -0,0 +1,31 @@ +/* + * Unix SMB/CIFS implementation. + * + * Window Search Service + * + * Copyright (c) 2016 Noel Power + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#ifndef __LIBRPC_WSP_HELPER_H__ +#define __LIBRPC_WSP_HELPER_H__ + +struct safearraybound; +struct wsp_hyper; + +uint32_t calc_array_size(struct safearraybound *bounds, uint32_t ndims); +void uint64_to_wsp_hyper(uint64_t src, struct wsp_hyper *dest); +void wsp_hyper_to_uint64(struct wsp_hyper *src, uint64_t *dest); + +#endif // __LIBRPC_WSP_HELPER_H__ diff --git a/librpc/wscript_build b/librpc/wscript_build index 1c7cc0a..1d07b42 100644 --- a/librpc/wscript_build +++ b/librpc/wscript_build @@ -330,6 +330,16 @@ bld.SAMBA_SUBSYSTEM('NDR_FSRVP', public_deps='ndr' ) +bld.SAMBA_SUBSYSTEM('NDR_WSP', + source='gen_ndr/ndr_wsp.c rpc/wsp_helper.c', + public_deps='ndr' + ) + +bld.SAMBA_SUBSYSTEM('NDR_WSP_DATA', + source='gen_ndr/ndr_wsp_data.c', + public_deps='ndr' + ) + bld.SAMBA_SUBSYSTEM('NDR_WITNESS', source='gen_ndr/ndr_witness.c ndr/ndr_witness.c', public_deps='ndr' @@ -685,7 +695,7 @@ bld.SAMBA_LIBRARY('ndr-samba', source=[], deps='''NDR_DRSBLOBS NDR_DRSUAPI NDR_IDMAP NDR_NTLMSSP NDR_NEGOEX NDR_SCHANNEL NDR_MGMT NDR_DNSSERVER NDR_EPMAPPER NDR_XATTR NDR_UNIXINFO NDR_NAMED_PIPE_AUTH NDR_DCOM - NDR_NTPRINTING NDR_FSRVP NDR_WITNESS NDR_MDSSVC NDR_OPEN_FILES NDR_SMBXSRV''', + NDR_NTPRINTING NDR_FSRVP NDR_WITNESS NDR_MDSSVC NDR_OPEN_FILES NDR_SMBXSRV NDR_WSP''', private_library=True, grouping_library=True ) -- 2.10.2 >From 948479c4e46185fb1c931a4108704a8f8a40c47f Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 26 Jul 2016 11:47:43 +0100 Subject: [PATCH 07/10] s3/build: Add support for WSP in configure script. Building the wsp service daemon and cli client can be controlled by specifying '--enable-wsp' Note: By default this option is not enabled. --- source3/wscript | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source3/wscript b/source3/wscript index c6b2421..ca8102f 100644 --- a/source3/wscript +++ b/source3/wscript @@ -76,6 +76,7 @@ def set_options(opt): action="store_true", dest='enable_vxfs', default=False) opt.SAMBA3_ADD_OPTION('spotlight', with_name="enable", without_name="disable", default=False) + opt.SAMBA3_ADD_OPTION('wsp', with_name="enable", without_name="disable", default=False) def configure(conf): from samba_utils import TO_LIST @@ -1643,6 +1644,11 @@ main() { conf.env['libtracker']='' conf.env.with_spotlight = False + conf.env.with_wsp = False + if Options.options.with_wsp: + Logs.info("building with WSP support") + conf.DEFINE('WITH_WSP', '1') + conf.env.with_wsp = True if Options.options.with_spotlight: versions = ['1.0', '0.16', '0.14'] for version in versions: -- 2.10.2 >From 2adde9f182a91082b6e69934854f18f5fb3dd45d Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 26 Jul 2016 12:23:38 +0100 Subject: [PATCH 08/10] librpc/rpc: Add windows propertyset info and associated accessor and helper api. Signed-off-by: Noel Power --- librpc/rpc/wsp_helper.c | 2074 +++++++++++++++++++++++++++++++++++++++++++++++ librpc/rpc/wsp_helper.h | 61 +- 2 files changed, 2134 insertions(+), 1 deletion(-) diff --git a/librpc/rpc/wsp_helper.c b/librpc/rpc/wsp_helper.c index 3d88a88..debf31d 100644 --- a/librpc/rpc/wsp_helper.c +++ b/librpc/rpc/wsp_helper.c @@ -50,3 +50,2077 @@ uint32_t calc_array_size(struct safearraybound *bounds, uint32_t ndims) } return result; } + +struct full_guid_propset { + struct GUID guid; + const struct full_propset_info *prop_info; +}; + +static const struct full_propset_info guid_properties_0[] = { + {0x64,"System.Calendar.IsOnline",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_1[] = { + {0x64,"System.Contact.OtherAddressStreet",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_2[] = { + {0x64,"System.ThumbnailCacheId",VT_UI8, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_3[] = { + {0x2,"System.DRM.IsProtected",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_4[] = { + {0x64,"System.Calendar.OptionalAttendeeNames",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_5[] = { + {0x64,"System.Calendar.ShowTimeAs",VT_UI2, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_6[] = { + {0x3,"System.Kind",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_7[] = { + {0x8,"System.Message.HasAttachments",VT_BOOL, true, false, true, false, 2}, + {0x5,"System.Priority",VT_UI2, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_8[] = { + {0x64,"System.ParentalRatingReason",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_9[] = { + {0x64,"System.Contact.OtherAddressCountry",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_10[] = { + {0x9,"System.Status",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_11[] = { + {0x64,"System.DateArchived",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_12[] = { + {0x64,"System.Contact.CarTelephone",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_13[] = { + {0x5,"System.ComputerName",VT_LPWSTR, true, false, true, false, 512}, + {0x8,"System.ItemPathDisplayNarrow",VT_LPWSTR, true, false, true, false, 520}, + {0xb,"System.ItemType",VT_LPWSTR, true, true, true, false, 512}, + {0x18,"System.ParsingName",VT_LPWSTR, true, true, true, false, 520}, + {0x19,"System.SFGAOFlags",VT_UI4, true, false, true, false, 4}, + {0x9,"PercivedType",VT_I4, false, false, false, true, 0}, + {0xc,"FileCount",VT_UI8, false, false, false, true, 0}, + {0xe,"TotalFileSize",VT_UI8, false, false, false, true, 0}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_14[] = { + {0x64,"System.Calendar.ResponseStatus",VT_UI2, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_15[] = { + {0x64,"System.Task.BillingInformation",VT_LPWSTR, true, true, false, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_16[] = { + {0x64,"System.Calendar.Duration",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_17[] = { + {0x64,"System.Message.SenderName",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_18[] = { + {0x64,"System.Document.DocumentID",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_19[] = { + {0x64,"System.RecordedTV.NetworkAffiliation",VT_LPWSTR, true, false, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_20[] = { + {0x64,"System.PriorityText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_21[] = { + {0x64,"System.Contact.Children",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_22[] = { + {0x64,"System.RecordedTV.RecordingTime",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_23[] = { + {0x64,"System.FlagColorText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_24[] = { + {0x64,"System.Contact.OtherAddressPostalCode",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_25[] = { + {0x64,"System.Photo.SharpnessText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_26[] = { + {0x64,"System.Contact.OtherAddress",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_27[] = { + {0x2,"System.Search.AutoSummary",VT_LPWSTR, true, false, true, false, 2048}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_28[] = { + {0x64,"System.Contact.BusinessAddress",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_29[] = { + {0x64,"System.IsIncomplete",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_30[] = { + {0x64,"System.Contact.EmailAddress2",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_31[] = { + {0x64,"System.Contact.BusinessTelephone",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_32[] = { + {0x64,"System.RecordedTV.StationName",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_33[] = { + {0xa,"System.ContentUrl",VT_LPWSTR, true, true, true, false, 4168}, + {0x9,"System.ItemUrl",VT_LPWSTR, true, true, true, false, 4168}, + {0x5,"System.Search.EntryID",VT_I4, true, false, true, false, 4}, + {0x4,"System.Search.HitCount",VT_I4, true, false, true, false, 4}, + {0x3,"System.Search.Rank",VT_I4, true, false, true, false, 4}, + {0x8,"System.Search.ReverseFileName",VT_LPWSTR, true, true, true, false, 520}, + {0x2,"RankVector",VT_UI4 | VT_VECTOR, false, false, false, true, 0}, + {0x6,"All",VT_LPWSTR, false, false, false, true, 0}, + {0xf,"System.Important.Unknown",VT_I4, false, false, false, true, 0}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_34[] = { + {0x64,"System.Image.CompressionText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_35[] = { + {0x64,"System.Contact.HomeAddressState",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_36[] = { + {0x64,"System.Contact.EmailAddress3",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_37[] = { + {0x64,"System.Music.IsCompilation",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_38[] = { + {0x64,"System.Communication.FollowupIconIndex",VT_I4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_39[] = { + {0x64,"System.Photo.TagViewAggregate",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_40[] = { + {0x64,"System.Message.ToDoTitle",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_41[] = { + {0x64,"System.Search.Store",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_42[] = { + {0x64,"System.FileName",VT_LPWSTR, true, true, true, false, 520}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_43[] = { + {0x64,"System.Contact.HomeAddressStreet",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_44[] = { + {0x64,"System.Contact.HomeAddressPostalCode",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_45[] = { + {0x64,"System.Contact.BusinessHomePage",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_46[] = { + {0x64,"System.Message.ConversationID",VT_LPWSTR, true, true, true, false, 512}, + {0x65,"System.Message.ConversationIndex",VT_BLOB_OBJECT, true, false, true, false, 1024}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_47[] = { + {0x64,"System.Calendar.RequiredAttendeeNames",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_48[] = { + {0xb,"System.Copyright",VT_LPWSTR, true, true, true, false, 512}, + {0xd,"System.Media.ClassPrimaryID",VT_LPWSTR, true, false, true, false, 512}, + {0xe,"System.Media.ClassSecondaryID",VT_LPWSTR, true, false, true, false, 512}, + {0x18,"System.Media.CollectionGroupID",VT_LPWSTR, true, false, true, false, 512}, + {0x19,"System.Media.CollectionID",VT_LPWSTR, true, false, true, false, 512}, + {0x12,"System.Media.ContentDistributor",VT_LPWSTR, true, false, true, false, 512}, + {0x1a,"System.Media.ContentID",VT_LPWSTR, true, false, true, false, 512}, + {0x1b,"System.Media.CreatorApplication",VT_LPWSTR, true, true, true, false, 512}, + {0x1c,"System.Media.CreatorApplicationVersion",VT_LPWSTR, true, true, true, false, 512}, + {0xf,"System.Media.DVDID",VT_LPWSTR, true, false, true, false, 512}, + {0x24,"System.Media.EncodedBy",VT_LPWSTR, true, true, true, false, 512}, + {0x10,"System.Media.MCDI",VT_LPWSTR, true, false, true, false, 512}, + {0x11,"System.Media.MetadataContentProvider",VT_LPWSTR, true, false, true, false, 512}, + {0x16,"System.Media.Producer",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0x26,"System.Media.ProtectionType",VT_LPWSTR, true, false, true, false, 512}, + {0x27,"System.Media.ProviderRating",VT_LPWSTR, true, false, true, false, 512}, + {0x28,"System.Media.ProviderStyle",VT_LPWSTR, true, false, true, false, 512}, + {0x1e,"System.Media.Publisher",VT_LPWSTR, true, true, true, false, 512}, + {0x23,"System.Media.UniqueFileIdentifier",VT_LPWSTR, true, false, true, false, 512}, + {0x29,"System.Media.UserNoAutoInfo",VT_LPWSTR, true, false, true, false, 512}, + {0x22,"System.Media.UserWebUrl",VT_LPWSTR, true, false, true, false, 4168}, + {0x17,"System.Media.Writer",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0x13,"System.Music.Composer",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0x1f,"System.Music.Period",VT_LPWSTR, true, true, true, false, 512}, + {0x15,"System.ParentalRating",VT_LPWSTR, true, true, true, false, 512}, + {0x9,"System.Rating",VT_UI4, true, false, true, false, 4}, + {0x14,"System.Video.Director",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_49[] = { + {0x64,"System.Message.ProofInProgress",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_50[] = { + {0x64,"System.Contact.PrimaryAddressPostOfficeBox",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_51[] = { + {0x64,"System.Calendar.IsRecurring",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_52[] = { + {0x64,"System.Contact.HomeAddress",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_53[] = { + {0x64,"System.ItemParticipants",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_54[] = { + {0x64,"System.Media.DateReleased",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_55[] = { + {0x64,"System.Journal.Contacts",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_56[] = { + {0x64,"System.Contact.Gender",VT_LPWSTR, true, true, true, false, 512}, + {0x65,"System.Contact.GenderValue",VT_UI2, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_57[] = { + {0x67,"System.Message.MessageClass",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_58[] = { + {0x64,"System.FlagColor",VT_UI2, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_59[] = { + {0x64,"System.Calendar.OrganizerName",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_60[] = { + {0x3,"System.Link.TargetSFGAOFlagsStrings",VT_LPWSTR | VT_VECTOR, true, true, false, false, 512}, + {0x2,"System.Shell.SFGAOFlagsStrings",VT_LPWSTR | VT_VECTOR, true, true, false, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_61[] = { + {0x64,"System.Photo.PeopleNames",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_62[] = { + {0x7,"System.Audio.ChannelCount",VT_UI4, true, false, true, false, 4}, + {0x4,"System.Audio.EncodingBitrate",VT_UI4, true, false, true, false, 4}, + {0x5,"System.Audio.SampleRate",VT_UI4, true, false, true, false, 4}, + {0x6,"System.Audio.SampleSize",VT_UI4, true, false, true, false, 4}, + {0x3,"System.Media.Duration",VT_UI8, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_63[] = { + {0x2,"DBPROP_CI_CATALOG_NAME",VT_LPWSTR, false, false, false, true, 0}, + {0x3,"DBPROP_CI_INCLUDE_SCOPES",VT_LPWSTR | VT_VECTOR, false, false, false, true, 0}, + {0x4,"DBPROP_CI_SCOPE_FLAGS",VT_I4 | VT_VECTOR, false, false, false, true, 0}, + {0x7,"DBPROP_CI_QUERY_TYPE",VT_I4, false, false, false, true, 0}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_64[] = { + {0x2,"DBPROP_MACHINE",VT_BSTR, false, false, false, true, 0}, + {0x3,"DBPROP_CLIENT_CLSID",VT_CLSID, false, false, false, true, 0}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_65[] = { + {0x4752,"System.DateImported",VT_FILETIME, true, false, true, false, 8}, + {0x103,"System.Image.Compression",VT_UI2, true, false, true, false, 2}, + {0x9202,"System.Photo.Aperture",VT_R8, true, false, true, false, 8}, + {0x10f,"System.Photo.CameraManufacturer",VT_LPWSTR, true, true, true, false, 512}, + {0x110,"System.Photo.CameraModel",VT_LPWSTR, true, true, true, false, 512}, + {0x9003,"System.Photo.DateTaken",VT_FILETIME, true, false, true, false, 8}, + {0x4748,"System.Photo.Event",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0x9204,"System.Photo.ExposureBias",VT_R8, true, false, true, false, 8}, + {0x8822,"System.Photo.ExposureProgram",VT_UI4, true, false, true, false, 4}, + {0x829a,"System.Photo.ExposureTime",VT_R8, true, false, true, false, 8}, + {0x9209,"System.Photo.Flash",VT_UI1, true, false, true, false, 1}, + {0x829d,"System.Photo.FNumber",VT_R8, true, false, true, false, 8}, + {0x920a,"System.Photo.FocalLength",VT_R8, true, false, true, false, 8}, + {0x8827,"System.Photo.ISOSpeed",VT_UI2, true, false, true, false, 2}, + {0x9208,"System.Photo.LightSource",VT_UI4, true, false, true, false, 4}, + {0x9207,"System.Photo.MeteringMode",VT_UI2, true, false, true, false, 2}, + {0x112,"System.Photo.Orientation",VT_UI2, true, false, true, false, 2}, + {0x9201,"System.Photo.ShutterSpeed",VT_R8, true, false, true, false, 8}, + {0x9206,"System.Photo.SubjectDistance",VT_R8, true, false, true, false, 8}, + {0x131,"System.SoftwareUsed",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_66[] = { + {0x64,"System.Contact.TTYTDDTelephone",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_67[] = { + {0x2f,"System.Contact.Birthday",VT_FILETIME, true, false, true, false, 8}, + {0x41,"System.Contact.HomeAddressCity",VT_LPWSTR, true, true, true, false, 512}, + {0x14,"System.Contact.HomeTelephone",VT_LPWSTR, true, true, true, false, 512}, + {0x6,"System.Contact.JobTitle",VT_LPWSTR, true, true, true, false, 512}, + {0x47,"System.Contact.MiddleName",VT_LPWSTR, true, true, true, false, 256}, + {0x23,"System.Contact.MobileTelephone",VT_LPWSTR, true, true, true, false, 512}, + {0x4a,"System.Contact.NickName",VT_LPWSTR, true, true, true, false, 256}, + {0x7,"System.Contact.OfficeLocation",VT_LPWSTR, true, true, true, false, 512}, + {0x45,"System.Contact.PersonalTitle",VT_LPWSTR, true, true, true, false, 512}, + {0x30,"System.Contact.PrimaryEmailAddress",VT_LPWSTR, true, true, true, false, 256}, + {0x19,"System.Contact.PrimaryTelephone",VT_LPWSTR, true, true, true, false, 512}, + {0x49,"System.Contact.Suffix",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_68[] = { + {0x64,"System.Photo.PhotometricInterpretationText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_69[] = { + {0x64,"System.Contact.OtherAddressPostOfficeBox",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_70[] = { + {0x64,"System.Calendar.ReminderTime",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_71[] = { + {0x64,"System.Calendar.RequiredAttendeeAddresses",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_72[] = { + {0x64,"System.Calendar.OrganizerAddress",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_73[] = { + {0x64,"System.Photo.WhiteBalanceText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_74[] = { + {0x2,"System.Link.TargetParsingPath",VT_LPWSTR, true, false, true, false, 520}, + {0x8,"System.Link.TargetSFGAOFlags",VT_UI4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_75[] = { + {0x64,"System.IsAttachment",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_76[] = { + {0x64,"System.Photo.GainControlText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_77[] = { + {0x64,"System.Contact.Hobbies",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_78[] = { + {0x64,"System.Contact.HomeAddressPostOfficeBox",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_79[] = { + {0x64,"System.Contact.CompanyMainTelephone",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_80[] = { + {0x64,"System.IsFlagged",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_81[] = { + {0x64,"System.Contact.FirstName",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_82[] = { + {0xa,"System.IsEncrypted",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_83[] = { + {0x64,"System.Media.AverageLevel",VT_UI4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_84[] = { + {0x5,"System.MIMEType",VT_LPWSTR, true, true, true, false, 512}, + {0x9,"System.Search.AccessCount",VT_UI4, true, false, true, false, 4}, + {0x8,"System.Search.GatherTime",VT_FILETIME, true, false, true, false, 8}, + {0xb,"System.Search.LastIndexedTotalTime",VT_R8, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_85[] = { + {0x64,"System.Calendar.OptionalAttendeeAddresses",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_86[] = { + {0x64,"System.ProviderItemID",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_87[] = { + {0x64,"System.Contact.BusinessAddressCountry",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_88[] = { + {0x64,"System.Contact.EmailName",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_89[] = { + {0x64,"System.Photo.FocalLengthInFilm",VT_UI2, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_90[] = { + {0x64,"System.IsDeleted",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_91[] = { + {0x64,"System.Contact.IMAddress",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_92[] = { + {0x64,"System.DateAcquired",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_93[] = { + {0x64,"System.DateCompleted",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_94[] = { + {0x64,"System.ItemName",VT_LPWSTR, true, false, true, false, 520}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_95[] = { + {0x64,"System.Contact.PrimaryAddressPostalCode",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_96[] = { + {0x26,"System.Media.SubTitle",VT_LPWSTR, true, true, true, false, 512}, + {0x5,"System.Media.Year",VT_UI4, true, false, true, false, 4}, + {0xd,"System.Music.AlbumArtist",VT_LPWSTR, true, true, true, false, 256}, + {0x64,"System.Music.AlbumID",VT_LPWSTR, true, true, true, false, 2048}, + {0x4,"System.Music.AlbumTitle",VT_LPWSTR, true, true, true, false, 512}, + {0x2,"System.Music.Artist",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0x23,"System.Music.BeatsPerMinute",VT_LPWSTR, true, true, true, false, 512}, + {0x24,"System.Music.Conductor",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0x21,"System.Music.ContentGroupDescription",VT_LPWSTR, true, false, true, false, 512}, + {0xb,"System.Music.Genre",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0x22,"System.Music.InitialKey",VT_LPWSTR, true, true, true, false, 512}, + {0xc,"System.Music.Lyrics",VT_LPWSTR, true, true, false, false, 512}, + {0x27,"System.Music.Mood",VT_LPWSTR, true, true, true, false, 512}, + {0x25,"System.Music.PartOfSet",VT_LPWSTR, true, false, true, false, 512}, + {0x7,"System.Music.TrackNumber",VT_UI4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_97[] = { + {0x64,"System.Document.ClientID",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_98[] = { + {0x64,"System.Photo.ExposureProgramText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_99[] = { + {0x12,"System.ApplicationName",VT_LPWSTR, true, true, true, false, 512}, + {0x4,"System.Author",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0x6,"System.Comment",VT_LPWSTR, true, true, true, false, 2048}, + {0x10,"System.Document.CharacterCount",VT_I4, true, false, true, false, 4}, + {0xc,"System.Document.DateCreated",VT_FILETIME, true, false, true, false, 8}, + {0xb,"System.Document.DatePrinted",VT_FILETIME, true, false, true, false, 8}, + {0xd,"System.Document.DateSaved",VT_FILETIME, true, false, true, false, 8}, + {0x8,"System.Document.LastAuthor",VT_LPWSTR, true, true, true, false, 256}, + {0xe,"System.Document.PageCount",VT_I4, true, false, true, false, 4}, + {0x9,"System.Document.RevisionNumber",VT_LPWSTR, true, true, true, false, 512}, + {0xa,"System.Document.TotalEditingTime",VT_UI8, true, false, true, false, 8}, + {0xf,"System.Document.WordCount",VT_I4, true, false, true, false, 4}, + {0x5,"System.Keywords",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0x3,"System.Subject",VT_LPWSTR, true, true, true, false, 520}, + {0x2,"System.Title",VT_LPWSTR, true, true, true, false, 520}, + {0x7,"DocTemplate",VT_LPWSTR, false, false, false, true, 0}, + {0x11,"DocThumbnail",VT_BLOB_OBJECT, false, false, false, true, 0}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_100[] = { + {0x64,"System.Note.ColorText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_101[] = { + {0x64,"System.Photo.MeteringModeText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_102[] = { + {0x2,"System.Link.TargetExtension",VT_LPWSTR | VT_VECTOR, true, true, false, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_103[] = { + {0x64,"System.Contact.BusinessAddressState",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_104[] = { + {0x64,"System.Photo.OrientationText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_105[] = { + {0x64,"System.Contact.Label",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_106[] = { + {0x64,"System.Calendar.Location",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_107[] = { + {0x64,"System.Photo.SaturationText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_108[] = { + {0x64,"System.Contact.PrimaryAddressCity",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_109[] = { + {0x64,"System.Contact.Anniversary",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_110[] = { + {0x64,"System.Contact.FileAsName",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_111[] = { + {0x64,"System.GPS.Date",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_112[] = { + {0x2,"System.Contact.JA.CompanyNamePhonetic",VT_LPWSTR, true, true, true, false, 256}, + {0x3,"System.Contact.JA.FirstNamePhonetic",VT_LPWSTR, true, true, true, false, 512}, + {0x4,"System.Contact.JA.LastNamePhonetic",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_113[] = { + {0x64,"System.Communication.SecurityFlags",VT_I4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_114[] = { + {0x64,"System.Identity",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_115[] = { + {0x64,"System.Contact.BusinessAddressPostOfficeBox",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_116[] = { + {0x64,"System.FileExtension",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_117[] = { + {0x64,"System.AcquisitionID",VT_I4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_118[] = { + {0x64,"System.Contact.EmailAddresses",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_119[] = { + {0x2,"System.Category",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0xf,"System.Company",VT_LPWSTR, true, true, true, false, 512}, + {0x1b,"System.ContentStatus",VT_LPWSTR, true, true, true, false, 512}, + {0x1a,"System.ContentType",VT_LPWSTR, true, true, true, false, 512}, + {0x4,"System.Document.ByteCount",VT_I4, true, false, true, false, 4}, + {0x9,"System.Document.HiddenSlideCount",VT_I4, true, false, true, false, 4}, + {0x5,"System.Document.LineCount",VT_I4, true, false, true, false, 4}, + {0xe,"System.Document.Manager",VT_LPWSTR, true, true, true, false, 512}, + {0x6,"System.Document.ParagraphCount",VT_I4, true, false, true, false, 4}, + {0x3,"System.Document.PresentationFormat",VT_LPWSTR, true, true, true, false, 512}, + {0x7,"System.Document.SlideCount",VT_I4, true, false, true, false, 4}, + {0x1d,"System.Document.Version",VT_LPWSTR, true, false, true, false, 512}, + {0x1c,"System.Language",VT_LPWSTR, true, true, true, false, 512}, + {0x8,"DocNoteCount",VT_I4, false, false, false, true, 0}, + {0xd,"DocPartTitles",VT_LPWSTR | VT_VECTOR, false, false, false, true, 0}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_120[] = { + {0x64,"System.Communication.TaskStatus",VT_UI2, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_121[] = { + {0x64,"System.Contact.LastName",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_122[] = { + {0x64,"System.Communication.DateItemExpires",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_123[] = { + {0x64,"System.ImportanceText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_124[] = { + {0x64,"System.Search.ContainerHash",VT_LPWSTR, true, true, false, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_125[] = { + {0x64,"System.Contact.BusinessFaxNumber",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_126[] = { + {0xa,"System.Video.Compression",VT_LPWSTR, true, true, true, false, 512}, + {0x8,"System.Video.EncodingBitrate",VT_UI4, true, false, true, false, 4}, + {0x2c,"System.Video.FourCC",VT_UI4, true, false, true, false, 4}, + {0x4,"System.Video.FrameHeight",VT_UI4, true, false, true, false, 4}, + {0x6,"System.Video.FrameRate",VT_UI4, true, false, true, false, 4}, + {0x3,"System.Video.FrameWidth",VT_UI4, true, false, true, false, 4}, + {0x2a,"System.Video.HorizontalAspectRatio",VT_UI4, true, false, true, false, 4}, + {0x9,"System.Video.SampleSize",VT_UI4, true, false, true, false, 4}, + {0x2,"System.Video.StreamName",VT_LPWSTR, true, true, true, false, 512}, + {0x2b,"System.Video.TotalBitrate",VT_UI4, true, false, true, false, 4}, + {0x2d,"System.Video.VerticalAspectRatio",VT_UI4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_127[] = { + {0x1a,"System.IconIndex",VT_I4, true, false, true, false, 4}, + {0x2,"System.Link.TargetUrl",VT_LPWSTR, true, true, true, false, 4168}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_128[] = { + {0x64,"System.IsFlaggedComplete",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_129[] = { + {0x64,"System.Task.Owner",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_130[] = { + {0x64,"System.ItemFolderPathDisplayNarrow",VT_LPWSTR, true, true, true, false, 520}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_131[] = { + {0x64,"System.Photo.ProgramModeText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_132[] = { + {0x64,"System.Contact.PrimaryAddressCountry",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_133[] = { + {0x2,"System.Shell.OmitFromView",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_134[] = { + {0x64,"System.Contact.OtherAddressState",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_135[] = { + {0x64,"System.Message.AttachmentContents",VT_LPWSTR, true, true, false, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_136[] = { + {0x64,"System.Communication.TaskStatusText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_137[] = { + {0x64,"System.Communication.HeaderItem",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_138[] = { + {0x64,"System.Contact.EmailAddress",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_139[] = { + {0x64,"System.Contact.FullName",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_140[] = { + {0x64,"System.Document.Division",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_141[] = { + {0x64,"System.Contact.BusinessAddressPostalCode",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_142[] = { + {0x64,"System.ItemNamePrefix",VT_LPWSTR, true, false, true, false, 520}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_143[] = { + {0x64,"System.Photo.DigitalZoom",VT_R8, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_144[] = { + {0x64,"System.SourceItem",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_145[] = { + {0x64,"System.Photo.WhiteBalance",VT_UI4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_146[] = { + {0x64,"System.SensitivityText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_147[] = { + {0x2,"MSIDXSPROP_ROWSETQUERYSTATUS",VT_I4, false, false, false, true, 0}, + {0x3,"MSIDXSPROP_COMMAND_LOCALE_STRING",VT_BSTR, false, false, false, true, 0}, + {0x4,"MSIDXSPROP_QUERY_RESTRICTION",VT_BSTR, false, false, false, true, 0}, + {0x5,"MSIDXSPROP_PARSE_TREE",VT_BSTR, false, false, false, true, 0}, + {0x6,"MSIDXSPROP_MAX_RANK",VT_I4, false, false, false, true, 0}, + {0x7,"MSIDXSPROP_RESULTS_FOUND",VT_I4, false, false, false, true, 0}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_148[] = { + {0x64,"System.Photo.MaxAperture",VT_R8, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_149[] = { + {0x64,"System.Calendar.Resources",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_150[] = { + {0x64,"System.Contact.OtherAddressCity",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_151[] = { + {0x64,"System.Music.DisplayArtist",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_152[] = { + {0x64,"System.Message.SenderAddress",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_153[] = { + {0x64,"System.Contact.PrimaryAddressState",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_154[] = { + {0x64,"System.StartDate",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_155[] = { + {0x10,"System.DateAccessed",VT_FILETIME, true, false, true, false, 8}, + {0xf,"System.DateCreated",VT_FILETIME, true, false, true, false, 8}, + {0xe,"System.DateModified",VT_FILETIME, true, false, true, false, 8}, + {0xd,"System.FileAttributes",VT_UI4, true, false, true, false, 4}, + {0x15,"System.FileFRN",VT_UI8, true, false, true, false, 8}, + {0x2,"System.ItemFolderNameDisplay",VT_LPWSTR, true, true, true, false, 512}, + {0xa,"System.ItemNameDisplay",VT_LPWSTR, true, true, true, false, 520}, + {0x4,"System.ItemTypeText",VT_LPWSTR, true, true, true, false, 512}, + {0x13,"System.Search.Contents",VT_LPWSTR, true, true, false, false, 512}, + {0xc,"System.Size",VT_UI8, true, false, true, false, 8}, + {0x3,"ClassId",VT_CLSID, false, false, false, true, 0}, + {0x8,"FileIndex",VT_UI8, false, false, false, true, 0}, + {0x9,"USN",VT_I8, false, false, false, true, 0}, + {0xb,"Path",VT_LPWSTR, false, false, false, true, 0}, + {0x12,"AllocSize",VT_I8, false, false, false, true, 0}, + {0x14,"ShortFilename",VT_LPWSTR, false, false, false, true, 0}, + {0x16,"Scope",VT_LPWSTR, false, false, false, true, 0}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_156[] = { + {0x64,"System.Contact.BusinessAddressStreet",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_157[] = { + {0x64,"System.Sensitivity",VT_UI2, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_158[] = { + {0x64,"System.Contact.HomeAddressCountry",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_159[] = { + {0x64,"System.Task.CompletionStatus",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_160[] = { + {0x10,"System.Software.DateLastUsed",VT_FILETIME, true, true, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_161[] = { + {0x64,"System.Contact.Department",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_162[] = { + {0x64,"System.Calendar.ShowTimeAsText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_163[] = { + {0x4,"System.FileOwner",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_164[] = { + {0x64,"System.RecordedTV.OriginalBroadcastDate",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_165[] = { + {0x64,"System.IsFolder",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_166[] = { + {0x64,"System.DueDate",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_167[] = { + {0x3,"System.FileDescription",VT_LPWSTR, true, true, false, false, 512}, + {0x6,"System.OriginalFileName",VT_LPWSTR, true, true, true, false, 520}, + {0x7,"System.Software.ProductName",VT_LPWSTR, true, true, false, false, 512}, + {0x8,"System.Software.ProductVersion",VT_LPWSTR, true, true, false, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_168[] = { + {0x64,"System.MileageInformation",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_169[] = { + {0x7,"System.RecordedTV.ChannelNumber",VT_UI4, true, false, true, false, 4}, + {0xf,"System.RecordedTV.DateContentExpires",VT_FILETIME, true, false, true, false, 8}, + {0x2,"System.RecordedTV.EpisodeName",VT_LPWSTR, true, true, true, false, 512}, + {0x10,"System.RecordedTV.IsATSCContent",VT_BOOL, true, false, true, false, 2}, + {0xc,"System.RecordedTV.IsClosedCaptioningAvailable",VT_BOOL, true, false, true, false, 2}, + {0x11,"System.RecordedTV.IsDTVContent",VT_BOOL, true, false, true, false, 2}, + {0x12,"System.RecordedTV.IsHDContent",VT_BOOL, true, false, true, false, 2}, + {0xd,"System.RecordedTV.IsRepeatBroadcast",VT_BOOL, true, false, true, false, 2}, + {0xe,"System.RecordedTV.IsSAP",VT_BOOL, true, false, true, false, 2}, + {0x3,"System.RecordedTV.ProgramDescription",VT_LPWSTR, true, true, true, false, 2048}, + {0x5,"System.RecordedTV.StationCallSign",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_170[] = { + {0x64,"System.Audio.PeakValue",VT_UI4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_171[] = { + {0x64,"System.ItemDate",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_172[] = { + {0x64,"System.Contact.SpouseName",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_173[] = { + {0x64,"System.Message.Flags",VT_I4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_174[] = { + {0x64,"System.Contact.AssistantTelephone",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_175[] = { + {0x64,"System.KindText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_176[] = { + {0x64,"System.Photo.ContrastText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_177[] = { + {0x7,"System.Image.BitDepth",VT_UI4, true, false, true, false, 4}, + {0xd,"System.Image.Dimensions",VT_LPWSTR, true, true, true, false, 512}, + {0x5,"System.Image.HorizontalResolution",VT_R8, true, false, true, false, 8}, + {0x3,"System.Image.HorizontalSize",VT_UI4, true, false, true, false, 4}, + {0x6,"System.Image.VerticalResolution",VT_R8, true, false, true, false, 8}, + {0x4,"System.Image.VerticalSize",VT_UI4, true, false, true, false, 4}, + {0xc,"System.Media.FrameCount",VT_UI4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_178[] = { + {0x64,"System.Message.IsFwdOrReply",VT_I4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_179[] = { + {0x64,"System.ItemAuthors",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_180[] = { + {0x64,"System.Contact.TelexNumber",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_181[] = { + {0x64,"System.Communication.PolicyTag",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_182[] = { + {0x64,"System.Contact.HomeFaxNumber",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_183[] = { + {0x64,"System.FlagStatusText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_184[] = { + {0x64,"System.Contact.AssistantName",VT_LPWSTR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_185[] = { + {0x64,"System.Message.ToDoFlags",VT_I4, true, false, true, false, 4}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_186[] = { + {0x64,"System.RatingText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_187[] = { + {0x64,"System.Document.Contributor",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_188[] = { + {0x64,"System.Contact.CallbackTelephone",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_189[] = { + {0x64,"System.EndDate",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_190[] = { + {0x64,"System.Media.DateEncoded",VT_FILETIME, true, false, true, false, 8}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_191[] = { + {0x64,"System.Photo.FlashText",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_192[] = { + {0x64,"System.Photo.FlashFired",VT_BOOL, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_193[] = { + {0x64,"System.Contact.Profession",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_194[] = { + {0x64,"System.Contact.PagerTelephone",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_195[] = { + {0x2,"DBPROP_USECONTENTINDEX",VT_BOOL, false, false, false, true, 0}, + {0x3,"DBPROP_DEFERNONINDEXEDTRIMMING",VT_BOOL, false, false, false, true, 0}, + {0x4,"DBPROP_USEEXTENDEDDBTYPES",VT_BOOL, false, false, false, true, 0}, + {0x5,"DBPROP_IGNORENOISEONLYCLAUSES",VT_BOOL, false, false, false, true, 0}, + {0x6,"DBPROP_GENERICOPTIONS_STRING",VT_BSTR, false, false, false, true, 0}, + {0x7,"DBPROP_FIRSTROWS",VT_BOOL, false, false, false, true, 0}, + {0x8,"DBPROP_DEFERCATALOGVERIFICATION",VT_BOOL, false, false, false, true, 0}, + {0xa,"DBPROP_GENERATEPARSETREE",VT_BOOL, false, false, false, true, 0}, + {0xc,"DBPROP_FREETEXTANYTERM",VT_BOOL, false, false, false, true, 0}, + {0xd,"DBPROP_FREETEXTUSESTEMMING",VT_BOOL, false, false, false, true, 0}, + {0xe,"DBPROP_IGNORESBRI",VT_BOOL, false, false, false, true, 0}, + {0x10,"DBPROP_ENABLEROWSETEVENTS",VT_BOOL, false, false, false, true, 0}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_196[] = { + {0x64,"System.Contact.BusinessAddressCity",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_197[] = { + {0x64,"System.Media.SubscriptionContentId",VT_LPWSTR, true, false, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_198[] = { + {0x64,"System.Contact.PrimaryAddressStreet",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_199[] = { + {0x64,"System.Project",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_200[] = { + {0x64,"System.Note.Color",VT_UI2, true, false, true, false, 2}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_201[] = { + {0x9,"System.Communication.AccountName",VT_LPWSTR, true, true, true, false, 512}, + {0x12,"System.Contact.WebPage",VT_LPWSTR, true, true, true, false, 4168}, + {0xc,"System.FlagStatus",VT_I4, true, false, true, false, 4}, + {0xb,"System.Importance",VT_I4, true, false, true, false, 4}, + {0xa,"System.IsRead",VT_BOOL, true, false, true, false, 2}, + {0x6,"System.ItemFolderPathDisplay",VT_LPWSTR, true, true, true, false, 520}, + {0x7,"System.ItemPathDisplay",VT_LPWSTR, true, true, true, false, 520}, + {0x15,"System.Message.AttachmentNames",VT_LPWSTR | VT_VECTOR, true, true, true, false, 512}, + {0x2,"System.Message.BccAddress",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0x3,"System.Message.BccName",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0x4,"System.Message.CcAddress",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0x5,"System.Message.CcName",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0x14,"System.Message.DateReceived",VT_FILETIME, true, false, true, false, 8}, + {0x13,"System.Message.DateSent",VT_FILETIME, true, false, true, false, 8}, + {0xd,"System.Message.FromAddress",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0xe,"System.Message.FromName",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0xf,"System.Message.Store",VT_LPWSTR, true, false, true, false, 512}, + {0x10,"System.Message.ToAddress",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0x11,"System.Message.ToName",VT_LPWSTR | VT_VECTOR, true, true, true, false, 256}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_202[] = { + {0x64,"System.Journal.EntryType",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + +static const struct full_propset_info guid_properties_203[] = { + {0x64,"System.Contact.MailingAddress",VT_LPWSTR, true, true, true, false, 512}, + {0,NULL} +}; + + +static struct full_guid_propset full_propertyset[] = { + {{0xBFEE9149, 0xE3E2, 0x49A7, {0xA8, 0x62}, {0xC0, 0x59, 0x88, 0x14, 0x5C, 0xEC}},guid_properties_0}, + {{0xFF962609, 0xB7D6, 0x4999, {0x86, 0x2D}, {0x95, 0x18, 0x0D, 0x52, 0x9A, 0xEA}},guid_properties_1}, + {{0x446D16B1, 0x8DAD, 0x4870, {0xA7, 0x48}, {0x40, 0x2E, 0xA4, 0x3D, 0x78, 0x8C}},guid_properties_2}, + {{0xAEAC19E4, 0x89AE, 0x4508, {0xB9, 0xB7}, {0xBB, 0x86, 0x7A, 0xBE, 0xE2, 0xED}},guid_properties_3}, + {{0x09429607, 0x582D, 0x437F, {0x84, 0xC3}, {0xDE, 0x93, 0xA2, 0xB2, 0x4C, 0x3C}},guid_properties_4}, + {{0x5BF396D4, 0x5EB2, 0x466F, {0xBD, 0xE9}, {0x2F, 0xB3, 0xF2, 0x36, 0x1D, 0x6E}},guid_properties_5}, + {{0x1E3EE840, 0xBC2B, 0x476C, {0x82, 0x37}, {0x2A, 0xCD, 0x1A, 0x83, 0x9B, 0x22}},guid_properties_6}, + {{0x9C1FCF74, 0x2D97, 0x41BA, {0xB4, 0xAE}, {0xCB, 0x2E, 0x36, 0x61, 0xA6, 0xE4}},guid_properties_7}, + {{0x10984E0A, 0xF9F2, 0x4321, {0xB7, 0xEF}, {0xBA, 0xF1, 0x95, 0xAF, 0x43, 0x19}},guid_properties_8}, + {{0x8F167568, 0x0AAE, 0x4322, {0x8E, 0xD9}, {0x60, 0x55, 0xB7, 0xB0, 0xE3, 0x98}},guid_properties_9}, + {{0x000214A1, 0x0000, 0x0000, {0xC0, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x46}},guid_properties_10}, + {{0x43F8D7B7, 0xA444, 0x4F87, {0x93, 0x83}, {0x52, 0x27, 0x1C, 0x9B, 0x91, 0x5C}},guid_properties_11}, + {{0x8FDC6DEA, 0xB929, 0x412B, {0xBA, 0x90}, {0x39, 0x7A, 0x25, 0x74, 0x65, 0xFE}},guid_properties_12}, + {{0x28636AA6, 0x953D, 0x11D2, {0xB5, 0xD6}, {0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xD0}},guid_properties_13}, + {{0x188C1F91, 0x3C40, 0x4132, {0x9E, 0xC5}, {0xD8, 0xB0, 0x3B, 0x72, 0xA8, 0xA2}},guid_properties_14}, + {{0xD37D52C6, 0x261C, 0x4303, {0x82, 0xB3}, {0x08, 0xB9, 0x26, 0xAC, 0x6F, 0x12}},guid_properties_15}, + {{0x293CA35A, 0x09AA, 0x4DD2, {0xB1, 0x80}, {0x1F, 0xE2, 0x45, 0x72, 0x8A, 0x52}},guid_properties_16}, + {{0x0DA41CFA, 0xD224, 0x4A18, {0xAE, 0x2F}, {0x59, 0x61, 0x58, 0xDB, 0x4B, 0x3A}},guid_properties_17}, + {{0xE08805C8, 0xE395, 0x40DF, {0x80, 0xD2}, {0x54, 0xF0, 0xD6, 0xC4, 0x31, 0x54}},guid_properties_18}, + {{0x2C53C813, 0xFB63, 0x4E22, {0xA1, 0xAB}, {0x0B, 0x33, 0x1C, 0xA1, 0xE2, 0x73}},guid_properties_19}, + {{0xD98BE98B, 0xB86B, 0x4095, {0xBF, 0x52}, {0x9D, 0x23, 0xB2, 0xE0, 0xA7, 0x52}},guid_properties_20}, + {{0xD4729704, 0x8EF1, 0x43EF, {0x90, 0x24}, {0x2B, 0xD3, 0x81, 0x18, 0x7F, 0xD5}},guid_properties_21}, + {{0xA5477F61, 0x7A82, 0x4ECA, {0x9D, 0xDE}, {0x98, 0xB6, 0x9B, 0x24, 0x79, 0xB3}},guid_properties_22}, + {{0x45EAE747, 0x8E2A, 0x40AE, {0x8C, 0xBF}, {0xCA, 0x52, 0xAB, 0xA6, 0x15, 0x2A}},guid_properties_23}, + {{0x95C656C1, 0x2ABF, 0x4148, {0x9E, 0xD3}, {0x9E, 0xC6, 0x02, 0xE3, 0xB7, 0xCD}},guid_properties_24}, + {{0x51EC3F47, 0xDD50, 0x421D, {0x87, 0x69}, {0x33, 0x4F, 0x50, 0x42, 0x4B, 0x1E}},guid_properties_25}, + {{0x508161FA, 0x313B, 0x43D5, {0x83, 0xA1}, {0xC1, 0xAC, 0xCF, 0x68, 0x62, 0x2C}},guid_properties_26}, + {{0x560C36C0, 0x503A, 0x11CF, {0xBA, 0xA1}, {0x00, 0x00, 0x4C, 0x75, 0x2A, 0x9A}},guid_properties_27}, + {{0x730FB6DD, 0xCF7C, 0x426B, {0xA0, 0x3F}, {0xBD, 0x16, 0x6C, 0xC9, 0xEE, 0x24}},guid_properties_28}, + {{0x346C8BD1, 0x2E6A, 0x4C45, {0x89, 0xA4}, {0x61, 0xB7, 0x8E, 0x8E, 0x70, 0x0F}},guid_properties_29}, + {{0x38965063, 0xEDC8, 0x4268, {0x84, 0x91}, {0xB7, 0x72, 0x31, 0x72, 0xCF, 0x29}},guid_properties_30}, + {{0x6A15E5A0, 0x0A1E, 0x4CD7, {0xBB, 0x8C}, {0xD2, 0xF1, 0xB0, 0xC9, 0x29, 0xBC}},guid_properties_31}, + {{0x1B5439E7, 0xEBA1, 0x4AF8, {0xBD, 0xD7}, {0x7A, 0xF1, 0xD4, 0x54, 0x94, 0x93}},guid_properties_32}, + {{0x49691C90, 0x7E17, 0x101A, {0xA9, 0x1C}, {0x08, 0x00, 0x2B, 0x2E, 0xCD, 0xA9}},guid_properties_33}, + {{0x3F08E66F, 0x2F44, 0x4BB9, {0xA6, 0x82}, {0xAC, 0x35, 0xD2, 0x56, 0x23, 0x22}},guid_properties_34}, + {{0xC89A23D0, 0x7D6D, 0x4EB8, {0x87, 0xD4}, {0x77, 0x6A, 0x82, 0xD4, 0x93, 0xE5}},guid_properties_35}, + {{0x644D37B4, 0xE1B3, 0x4BAD, {0xB0, 0x99}, {0x7E, 0x7C, 0x04, 0x96, 0x6A, 0xCA}},guid_properties_36}, + {{0xC449D5CB, 0x9EA4, 0x4809, {0x82, 0xE8}, {0xAF, 0x9D, 0x59, 0xDE, 0xD6, 0xD1}},guid_properties_37}, + {{0x83A6347E, 0x6FE4, 0x4F40, {0xBA, 0x9C}, {0xC4, 0x86, 0x52, 0x40, 0xD1, 0xF4}},guid_properties_38}, + {{0xB812F15D, 0xC2D8, 0x4BBF, {0xBA, 0xCD}, {0x79, 0x74, 0x43, 0x46, 0x11, 0x3F}},guid_properties_39}, + {{0xBCCC8A3C, 0x8CEF, 0x42E5, {0x9B, 0x1C}, {0xC6, 0x90, 0x79, 0x39, 0x8B, 0xC7}},guid_properties_40}, + {{0xA06992B3, 0x8CAF, 0x4ED7, {0xA5, 0x47}, {0xB2, 0x59, 0xE3, 0x2A, 0xC9, 0xFC}},guid_properties_41}, + {{0x41CF5AE0, 0xF75A, 0x4806, {0xBD, 0x87}, {0x59, 0xC7, 0xD9, 0x24, 0x8E, 0xB9}},guid_properties_42}, + {{0x0ADEF160, 0xDB3F, 0x4308, {0x9A, 0x21}, {0x06, 0x23, 0x7B, 0x16, 0xFA, 0x2A}},guid_properties_43}, + {{0x8AFCC170, 0x8A46, 0x4B53, {0x9E, 0xEE}, {0x90, 0xBA, 0xE7, 0x15, 0x1E, 0x62}},guid_properties_44}, + {{0x56310920, 0x2491, 0x4919, {0x99, 0xCE}, {0xEA, 0xDB, 0x06, 0xFA, 0xFD, 0xB2}},guid_properties_45}, + {{0xDC8F80BD, 0xAF1E, 0x4289, {0x85, 0xB6}, {0x3D, 0xFC, 0x1B, 0x49, 0x39, 0x92}},guid_properties_46}, + {{0xB33AF30B, 0xF552, 0x4584, {0x93, 0x6C}, {0xCB, 0x93, 0xE5, 0xCD, 0xA2, 0x9F}},guid_properties_47}, + {{0x64440492, 0x4C8B, 0x11D1, {0x8B, 0x70}, {0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03}},guid_properties_48}, + {{0x9098F33C, 0x9A7D, 0x48A8, {0x8D, 0xE5}, {0x2E, 0x12, 0x27, 0xA6, 0x4E, 0x91}},guid_properties_49}, + {{0xDE5EF3C7, 0x46E1, 0x484E, {0x99, 0x99}, {0x62, 0xC5, 0x30, 0x83, 0x94, 0xC1}},guid_properties_50}, + {{0x315B9C8D, 0x80A9, 0x4EF9, {0xAE, 0x16}, {0x8E, 0x74, 0x6D, 0xA5, 0x1D, 0x70}},guid_properties_51}, + {{0x98F98354, 0x617A, 0x46B8, {0x85, 0x60}, {0x5B, 0x1B, 0x64, 0xBF, 0x1F, 0x89}},guid_properties_52}, + {{0xD4D0AA16, 0x9948, 0x41A4, {0xAA, 0x85}, {0xD9, 0x7F, 0xF9, 0x64, 0x69, 0x93}},guid_properties_53}, + {{0xDE41CC29, 0x6971, 0x4290, {0xB4, 0x72}, {0xF5, 0x9F, 0x2E, 0x2F, 0x31, 0xE2}},guid_properties_54}, + {{0xDEA7C82C, 0x1D89, 0x4A66, {0x94, 0x27}, {0xA4, 0xE3, 0xDE, 0xBA, 0xBC, 0xB1}},guid_properties_55}, + {{0x3C8CEE58, 0xD4F0, 0x4CF9, {0xB7, 0x56}, {0x4E, 0x5D, 0x24, 0x44, 0x7B, 0xCD}},guid_properties_56}, + {{0xCD9ED458, 0x08CE, 0x418F, {0xA7, 0x0E}, {0xF9, 0x12, 0xC7, 0xBB, 0x9C, 0x5C}},guid_properties_57}, + {{0x67DF94DE, 0x0CA7, 0x4D6F, {0xB7, 0x92}, {0x05, 0x3A, 0x3E, 0x4F, 0x03, 0xCF}},guid_properties_58}, + {{0xAAA660F9, 0x9865, 0x458E, {0xB4, 0x84}, {0x01, 0xBC, 0x7F, 0xE3, 0x97, 0x3E}},guid_properties_59}, + {{0xD6942081, 0xD53B, 0x443D, {0xAD, 0x47}, {0x5E, 0x05, 0x9D, 0x9C, 0xD2, 0x7A}},guid_properties_60}, + {{0xE8309B6E, 0x084C, 0x49B4, {0xB1, 0xFC}, {0x90, 0xA8, 0x03, 0x31, 0xB6, 0x38}},guid_properties_61}, + {{0x64440490, 0x4C8B, 0x11D1, {0x8B, 0x70}, {0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03}},guid_properties_62}, + {{0xA9BD1526, 0x6A80, 0x11D0, {0x8C, 0x9D}, {0x00, 0x20, 0xAF, 0x1D, 0x74, 0x0E}},guid_properties_63}, + {{0xAFAFACA5, 0xB5D1, 0x11D0, {0x8C, 0x62}, {0x00, 0xC0, 0x4F, 0xC2, 0xDB, 0x8D}},guid_properties_64}, + {{0x14B81DA1, 0x0135, 0x4D31, {0x96, 0xD9}, {0x6C, 0xBF, 0xC9, 0x67, 0x1A, 0x99}},guid_properties_65}, + {{0xAAF16BAC, 0x2B55, 0x45E6, {0x9F, 0x6D}, {0x41, 0x5E, 0xB9, 0x49, 0x10, 0xDF}},guid_properties_66}, + {{0x176DC63C, 0x2688, 0x4E89, {0x81, 0x43}, {0xA3, 0x47, 0x80, 0x0F, 0x25, 0xE9}},guid_properties_67}, + {{0x821437D6, 0x9EAB, 0x4765, {0xA5, 0x89}, {0x3B, 0x1C, 0xBB, 0xD2, 0x2A, 0x61}},guid_properties_68}, + {{0x8B26EA41, 0x058F, 0x43F6, {0xAE, 0xCC}, {0x40, 0x35, 0x68, 0x1C, 0xE9, 0x77}},guid_properties_69}, + {{0x72FC5BA4, 0x24F9, 0x4011, {0x9F, 0x3F}, {0xAD, 0xD2, 0x7A, 0xFA, 0xD8, 0x18}},guid_properties_70}, + {{0x0BA7D6C3, 0x568D, 0x4159, {0xAB, 0x91}, {0x78, 0x1A, 0x91, 0xFB, 0x71, 0xE5}},guid_properties_71}, + {{0x744C8242, 0x4DF5, 0x456C, {0xAB, 0x9E}, {0x01, 0x4E, 0xFB, 0x90, 0x21, 0xE3}},guid_properties_72}, + {{0x6336B95E, 0xC7A7, 0x426D, {0x86, 0xFD}, {0x7A, 0xE3, 0xD3, 0x9C, 0x84, 0xB4}},guid_properties_73}, + {{0xB9B4B3FC, 0x2B51, 0x4A42, {0xB5, 0xD8}, {0x32, 0x41, 0x46, 0xAF, 0xCF, 0x25}},guid_properties_74}, + {{0xF23F425C, 0x71A1, 0x4FA8, {0x92, 0x2F}, {0x67, 0x8E, 0xA4, 0xA6, 0x04, 0x08}},guid_properties_75}, + {{0xC06238B2, 0x0BF9, 0x4279, {0xA7, 0x23}, {0x25, 0x85, 0x67, 0x15, 0xCB, 0x9D}},guid_properties_76}, + {{0x5DC2253F, 0x5E11, 0x4ADF, {0x9C, 0xFE}, {0x91, 0x0D, 0xD0, 0x1E, 0x3E, 0x70}},guid_properties_77}, + {{0x7B9F6399, 0x0A3F, 0x4B12, {0x89, 0xBD}, {0x4A, 0xDC, 0x51, 0xC9, 0x18, 0xAF}},guid_properties_78}, + {{0x8589E481, 0x6040, 0x473D, {0xB1, 0x71}, {0x7F, 0xA8, 0x9C, 0x27, 0x08, 0xED}},guid_properties_79}, + {{0x5DA84765, 0xE3FF, 0x4278, {0x86, 0xB0}, {0xA2, 0x79, 0x67, 0xFB, 0xDD, 0x03}},guid_properties_80}, + {{0x14977844, 0x6B49, 0x4AAD, {0xA7, 0x14}, {0xA4, 0x51, 0x3B, 0xF6, 0x04, 0x60}},guid_properties_81}, + {{0x90E5E14E, 0x648B, 0x4826, {0xB2, 0xAA}, {0xAC, 0xAF, 0x79, 0x0E, 0x35, 0x13}},guid_properties_82}, + {{0x09EDD5B6, 0xB301, 0x43C5, {0x99, 0x90}, {0xD0, 0x03, 0x02, 0xEF, 0xFD, 0x46}},guid_properties_83}, + {{0x0B63E350, 0x9CCC, 0x11D0, {0xBC, 0xDB}, {0x00, 0x80, 0x5F, 0xCC, 0xCE, 0x04}},guid_properties_84}, + {{0xD55BAE5A, 0x3892, 0x417A, {0xA6, 0x49}, {0xC6, 0xAC, 0x5A, 0xAA, 0xEA, 0xB3}},guid_properties_85}, + {{0xF21D9941, 0x81F0, 0x471A, {0xAD, 0xEE}, {0x4E, 0x74, 0xB4, 0x92, 0x17, 0xED}},guid_properties_86}, + {{0xB0B87314, 0xFCF6, 0x4FEB, {0x8D, 0xFF}, {0xA5, 0x0D, 0xA6, 0xAF, 0x56, 0x1C}},guid_properties_87}, + {{0xCC6F4F24, 0x6083, 0x4BD4, {0x87, 0x54}, {0x67, 0x4D, 0x0D, 0xE8, 0x7A, 0xB8}},guid_properties_88}, + {{0xA0E74609, 0xB84D, 0x4F49, {0xB8, 0x60}, {0x46, 0x2B, 0xD9, 0x97, 0x1F, 0x98}},guid_properties_89}, + {{0x5CDA5FC8, 0x33EE, 0x4FF3, {0x90, 0x94}, {0xAE, 0x7B, 0xD8, 0x86, 0x8C, 0x4D}},guid_properties_90}, + {{0xD68DBD8A, 0x3374, 0x4B81, {0x99, 0x72}, {0x3E, 0xC3, 0x06, 0x82, 0xDB, 0x3D}},guid_properties_91}, + {{0x2CBAA8F5, 0xD81F, 0x47CA, {0xB1, 0x7A}, {0xF8, 0xD8, 0x22, 0x30, 0x01, 0x31}},guid_properties_92}, + {{0x72FAB781, 0xACDA, 0x43E5, {0xB1, 0x55}, {0xB2, 0x43, 0x4F, 0x85, 0xE6, 0x78}},guid_properties_93}, + {{0x6B8DA074, 0x3B5C, 0x43BC, {0x88, 0x6F}, {0x0A, 0x2C, 0xDC, 0xE0, 0x0B, 0x6F}},guid_properties_94}, + {{0x18BBD425, 0xECFD, 0x46EF, {0xB6, 0x12}, {0x7B, 0x4A, 0x60, 0x34, 0xED, 0xA0}},guid_properties_95}, + {{0x56A3372E, 0xCE9C, 0x11D2, {0x9F, 0x0E}, {0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6}},guid_properties_96}, + {{0x276D7BB0, 0x5B34, 0x4FB0, {0xAA, 0x4B}, {0x15, 0x8E, 0xD1, 0x2A, 0x18, 0x09}},guid_properties_97}, + {{0xFEC690B7, 0x5F30, 0x4646, {0xAE, 0x47}, {0x4C, 0xAA, 0xFB, 0xA8, 0x84, 0xA3}},guid_properties_98}, + {{0xF29F85E0, 0x4FF9, 0x1068, {0xAB, 0x91}, {0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9}},guid_properties_99}, + {{0x46B4E8DE, 0xCDB2, 0x440D, {0x88, 0x5C}, {0x16, 0x58, 0xEB, 0x65, 0xB9, 0x14}},guid_properties_100}, + {{0xF628FD8C, 0x7BA8, 0x465A, {0xA6, 0x5B}, {0xC5, 0xAA, 0x79, 0x26, 0x3A, 0x9E}},guid_properties_101}, + {{0x7A7D76F4, 0xB630, 0x4BD7, {0x95, 0xFF}, {0x37, 0xCC, 0x51, 0xA9, 0x75, 0xC9}},guid_properties_102}, + {{0x446F787F, 0x10C4, 0x41CB, {0xA6, 0xC4}, {0x4D, 0x03, 0x43, 0x55, 0x15, 0x97}},guid_properties_103}, + {{0xA9EA193C, 0xC511, 0x498A, {0xA0, 0x6B}, {0x58, 0xE2, 0x77, 0x6D, 0xCC, 0x28}},guid_properties_104}, + {{0x97B0AD89, 0xDF49, 0x49CC, {0x83, 0x4E}, {0x66, 0x09, 0x74, 0xFD, 0x75, 0x5B}},guid_properties_105}, + {{0xF6272D18, 0xCECC, 0x40B1, {0xB2, 0x6A}, {0x39, 0x11, 0x71, 0x7A, 0xA7, 0xBD}},guid_properties_106}, + {{0x61478C08, 0xB600, 0x4A84, {0xBB, 0xE4}, {0xE9, 0x9C, 0x45, 0xF0, 0xA0, 0x72}},guid_properties_107}, + {{0xC8EA94F0, 0xA9E3, 0x4969, {0xA9, 0x4B}, {0x9C, 0x62, 0xA9, 0x53, 0x24, 0xE0}},guid_properties_108}, + {{0x9AD5BADB, 0xCEA7, 0x4470, {0xA0, 0x3D}, {0xB8, 0x4E, 0x51, 0xB9, 0x94, 0x9E}},guid_properties_109}, + {{0xF1A24AA7, 0x9CA7, 0x40F6, {0x89, 0xEC}, {0x97, 0xDE, 0xF9, 0xFF, 0xE8, 0xDB}},guid_properties_110}, + {{0x3602C812, 0x0F3B, 0x45F0, {0x85, 0xAD}, {0x60, 0x34, 0x68, 0xD6, 0x94, 0x23}},guid_properties_111}, + {{0x897B3694, 0xFE9E, 0x43E6, {0x80, 0x66}, {0x26, 0x0F, 0x59, 0x0C, 0x01, 0x00}},guid_properties_112}, + {{0x8619A4B6, 0x9F4D, 0x4429, {0x8C, 0x0F}, {0xB9, 0x96, 0xCA, 0x59, 0xE3, 0x35}},guid_properties_113}, + {{0xA26F4AFC, 0x7346, 0x4299, {0xBE, 0x47}, {0xEB, 0x1A, 0xE6, 0x13, 0x13, 0x9F}},guid_properties_114}, + {{0xBC4E71CE, 0x17F9, 0x48D5, {0xBE, 0xE9}, {0x02, 0x1D, 0xF0, 0xEA, 0x54, 0x09}},guid_properties_115}, + {{0xE4F10A3C, 0x49E6, 0x405D, {0x82, 0x88}, {0xA2, 0x3B, 0xD4, 0xEE, 0xAA, 0x6C}},guid_properties_116}, + {{0x65A98875, 0x3C80, 0x40AB, {0xAB, 0xBC}, {0xEF, 0xDA, 0xF7, 0x7D, 0xBE, 0xE2}},guid_properties_117}, + {{0x84D8F337, 0x981D, 0x44B3, {0x96, 0x15}, {0xC7, 0x59, 0x6D, 0xBA, 0x17, 0xE3}},guid_properties_118}, + {{0xD5CDD502, 0x2E9C, 0x101B, {0x93, 0x97}, {0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE}},guid_properties_119}, + {{0xBE1A72C6, 0x9A1D, 0x46B7, {0xAF, 0xE7}, {0xAF, 0xAF, 0x8C, 0xEF, 0x49, 0x99}},guid_properties_120}, + {{0x8F367200, 0xC270, 0x457C, {0xB1, 0xD4}, {0xE0, 0x7C, 0x5B, 0xCD, 0x90, 0xC7}},guid_properties_121}, + {{0x428040AC, 0xA177, 0x4C8A, {0x97, 0x60}, {0xF6, 0xF7, 0x61, 0x22, 0x7F, 0x9A}},guid_properties_122}, + {{0xA3B29791, 0x7713, 0x4E1D, {0xBB, 0x40}, {0x17, 0xDB, 0x85, 0xF0, 0x18, 0x31}},guid_properties_123}, + {{0xBCEEE283, 0x35DF, 0x4D53, {0x82, 0x6A}, {0xF3, 0x6A, 0x3E, 0xEF, 0xC6, 0xBE}},guid_properties_124}, + {{0x91EFF6F3, 0x2E27, 0x42CA, {0x93, 0x3E}, {0x7C, 0x99, 0x9F, 0xBE, 0x31, 0x0B}},guid_properties_125}, + {{0x64440491, 0x4C8B, 0x11D1, {0x8B, 0x70}, {0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03}},guid_properties_126}, + {{0x5CBF2787, 0x48CF, 0x4208, {0xB9, 0x0E}, {0xEE, 0x5E, 0x5D, 0x42, 0x02, 0x94}},guid_properties_127}, + {{0xA6F360D2, 0x55F9, 0x48DE, {0xB9, 0x09}, {0x62, 0x0E, 0x09, 0x0A, 0x64, 0x7C}},guid_properties_128}, + {{0x08C7CC5F, 0x60F2, 0x4494, {0xAD, 0x75}, {0x55, 0xE3, 0xE0, 0xB5, 0xAD, 0xD0}},guid_properties_129}, + {{0xDABD30ED, 0x0043, 0x4789, {0xA7, 0xF8}, {0xD0, 0x13, 0xA4, 0x73, 0x66, 0x22}},guid_properties_130}, + {{0x7FE3AA27, 0x2648, 0x42F3, {0x89, 0xB0}, {0x45, 0x4E, 0x5C, 0xB1, 0x50, 0xC3}},guid_properties_131}, + {{0xE53D799D, 0x0F3F, 0x466E, {0xB2, 0xFF}, {0x74, 0x63, 0x4A, 0x3C, 0xB7, 0xA4}},guid_properties_132}, + {{0xDE35258C, 0xC695, 0x4CBC, {0xB9, 0x82}, {0x38, 0xB0, 0xAD, 0x24, 0xCE, 0xD0}},guid_properties_133}, + {{0x71B377D6, 0xE570, 0x425F, {0xA1, 0x70}, {0x80, 0x9F, 0xAE, 0x73, 0xE5, 0x4E}},guid_properties_134}, + {{0x3143BF7C, 0x80A8, 0x4854, {0x88, 0x80}, {0xE2, 0xE4, 0x01, 0x89, 0xBD, 0xD0}},guid_properties_135}, + {{0xA6744477, 0xC237, 0x475B, {0xA0, 0x75}, {0x54, 0xF3, 0x44, 0x98, 0x29, 0x2A}},guid_properties_136}, + {{0xC9C34F84, 0x2241, 0x4401, {0xB6, 0x07}, {0xBD, 0x20, 0xED, 0x75, 0xAE, 0x7F}},guid_properties_137}, + {{0xF8FA7FA3, 0xD12B, 0x4785, {0x8A, 0x4E}, {0x69, 0x1A, 0x94, 0xF7, 0xA3, 0xE7}},guid_properties_138}, + {{0x635E9051, 0x50A5, 0x4BA2, {0xB9, 0xDB}, {0x4E, 0xD0, 0x56, 0xC7, 0x72, 0x96}},guid_properties_139}, + {{0x1E005EE6, 0xBF27, 0x428B, {0xB0, 0x1C}, {0x79, 0x67, 0x6A, 0xCD, 0x28, 0x70}},guid_properties_140}, + {{0xE1D4A09E, 0xD758, 0x4CD1, {0xB6, 0xEC}, {0x34, 0xA8, 0xB5, 0xA7, 0x3F, 0x80}},guid_properties_141}, + {{0xD7313FF1, 0xA77A, 0x401C, {0x8C, 0x99}, {0x3D, 0xBD, 0xD6, 0x8A, 0xDD, 0x36}},guid_properties_142}, + {{0xF85BF840, 0xA925, 0x4BC2, {0xB0, 0xC4}, {0x8E, 0x36, 0xB5, 0x98, 0x67, 0x9E}},guid_properties_143}, + {{0x668CDFA5, 0x7A1B, 0x4323, {0xAE, 0x4B}, {0xE5, 0x27, 0x39, 0x3A, 0x1D, 0x81}},guid_properties_144}, + {{0xEE3D3D8A, 0x5381, 0x4CFA, {0xB1, 0x3B}, {0xAA, 0xF6, 0x6B, 0x5F, 0x4E, 0xC9}},guid_properties_145}, + {{0xD0C7F054, 0x3F72, 0x4725, {0x85, 0x27}, {0x12, 0x9A, 0x57, 0x7C, 0xB2, 0x69}},guid_properties_146}, + {{0xAA6EE6B0, 0xE828, 0x11D0, {0xB2, 0x3E}, {0x00, 0xAA, 0x00, 0x47, 0xFC, 0x01}},guid_properties_147}, + {{0x08F6D7C2, 0xE3F2, 0x44FC, {0xAF, 0x1E}, {0x5A, 0xA5, 0xC8, 0x1A, 0x2D, 0x3E}},guid_properties_148}, + {{0x00F58A38, 0xC54B, 0x4C40, {0x86, 0x96}, {0x97, 0x23, 0x59, 0x80, 0xEA, 0xE1}},guid_properties_149}, + {{0x6E682923, 0x7F7B, 0x4F0C, {0xA3, 0x37}, {0xCF, 0xCA, 0x29, 0x66, 0x87, 0xBF}},guid_properties_150}, + {{0xFD122953, 0xFA93, 0x4EF7, {0x92, 0xC3}, {0x04, 0xC9, 0x46, 0xB2, 0xF7, 0xC8}},guid_properties_151}, + {{0x0BE1C8E7, 0x1981, 0x4676, {0xAE, 0x14}, {0xFD, 0xD7, 0x8F, 0x05, 0xA6, 0xE7}},guid_properties_152}, + {{0xF1176DFE, 0x7138, 0x4640, {0x8B, 0x4C}, {0xAE, 0x37, 0x5D, 0xC7, 0x0A, 0x6D}},guid_properties_153}, + {{0x48FD6EC8, 0x8A12, 0x4CDF, {0xA0, 0x3E}, {0x4E, 0xC5, 0xA5, 0x11, 0xED, 0xDE}},guid_properties_154}, + {{0xB725F130, 0x47EF, 0x101A, {0xA5, 0xF1}, {0x02, 0x60, 0x8C, 0x9E, 0xEB, 0xAC}},guid_properties_155}, + {{0xDDD1460F, 0xC0BF, 0x4553, {0x8C, 0xE4}, {0x10, 0x43, 0x3C, 0x90, 0x8F, 0xB0}},guid_properties_156}, + {{0xF8D3F6AC, 0x4874, 0x42CB, {0xBE, 0x59}, {0xAB, 0x45, 0x4B, 0x30, 0x71, 0x6A}},guid_properties_157}, + {{0x08A65AA1, 0xF4C9, 0x43DD, {0x9D, 0xDF}, {0xA3, 0x3D, 0x8E, 0x7E, 0xAD, 0x85}},guid_properties_158}, + {{0x084D8A0A, 0xE6D5, 0x40DE, {0xBF, 0x1F}, {0xC8, 0x82, 0x0E, 0x7C, 0x87, 0x7C}},guid_properties_159}, + {{0x841E4F90, 0xFF59, 0x4D16, {0x89, 0x47}, {0xE8, 0x1B, 0xBF, 0xFA, 0xB3, 0x6D}},guid_properties_160}, + {{0xFC9F7306, 0xFF8F, 0x4D49, {0x9F, 0xB6}, {0x3F, 0xFE, 0x5C, 0x09, 0x51, 0xEC}},guid_properties_161}, + {{0x53DA57CF, 0x62C0, 0x45C4, {0x81, 0xDE}, {0x76, 0x10, 0xBC, 0xEF, 0xD7, 0xF5}},guid_properties_162}, + {{0x9B174B34, 0x40FF, 0x11D2, {0xA2, 0x7E}, {0x00, 0xC0, 0x4F, 0xC3, 0x08, 0x71}},guid_properties_163}, + {{0x4684FE97, 0x8765, 0x4842, {0x9C, 0x13}, {0xF0, 0x06, 0x44, 0x7B, 0x17, 0x8C}},guid_properties_164}, + {{0x09329B74, 0x40A3, 0x4C68, {0xBF, 0x07}, {0xAF, 0x9A, 0x57, 0x2F, 0x60, 0x7C}},guid_properties_165}, + {{0x3F8472B5, 0xE0AF, 0x4DB2, {0x80, 0x71}, {0xC5, 0x3F, 0xE7, 0x6A, 0xE7, 0xCE}},guid_properties_166}, + {{0x0CEF7D53, 0xFA64, 0x11D1, {0xA2, 0x03}, {0x00, 0x00, 0xF8, 0x1F, 0xED, 0xEE}},guid_properties_167}, + {{0xFDF84370, 0x031A, 0x4ADD, {0x9E, 0x91}, {0x0D, 0x77, 0x5F, 0x1C, 0x66, 0x05}},guid_properties_168}, + {{0x6D748DE2, 0x8D38, 0x4CC3, {0xAC, 0x60}, {0xF0, 0x09, 0xB0, 0x57, 0xC5, 0x57}},guid_properties_169}, + {{0x2579E5D0, 0x1116, 0x4084, {0xBD, 0x9A}, {0x9B, 0x4F, 0x7C, 0xB4, 0xDF, 0x5E}},guid_properties_170}, + {{0xF7DB74B4, 0x4287, 0x4103, {0xAF, 0xBA}, {0xF1, 0xB1, 0x3D, 0xCD, 0x75, 0xCF}},guid_properties_171}, + {{0x9D2408B6, 0x3167, 0x422B, {0x82, 0xB0}, {0xF5, 0x83, 0xB7, 0xA7, 0xCF, 0xE3}},guid_properties_172}, + {{0xA82D9EE7, 0xCA67, 0x4312, {0x96, 0x5E}, {0x22, 0x6B, 0xCE, 0xA8, 0x50, 0x23}},guid_properties_173}, + {{0x9A93244D, 0xA7AD, 0x4FF8, {0x9B, 0x99}, {0x45, 0xEE, 0x4C, 0xC0, 0x9A, 0xF6}},guid_properties_174}, + {{0xF04BEF95, 0xC585, 0x4197, {0xA2, 0xB7}, {0xDF, 0x46, 0xFD, 0xC9, 0xEE, 0x6D}},guid_properties_175}, + {{0x59DDE9F2, 0x5253, 0x40EA, {0x9A, 0x8B}, {0x47, 0x9E, 0x96, 0xC6, 0x24, 0x9A}},guid_properties_176}, + {{0x6444048F, 0x4C8B, 0x11D1, {0x8B, 0x70}, {0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03}},guid_properties_177}, + {{0x9A9BC088, 0x4F6D, 0x469E, {0x99, 0x19}, {0xE7, 0x05, 0x41, 0x20, 0x40, 0xF9}},guid_properties_178}, + {{0xD0A04F0A, 0x462A, 0x48A4, {0xBB, 0x2F}, {0x37, 0x06, 0xE8, 0x8D, 0xBD, 0x7D}},guid_properties_179}, + {{0xC554493C, 0xC1F7, 0x40C1, {0xA7, 0x6C}, {0xEF, 0x8C, 0x06, 0x14, 0x00, 0x3E}},guid_properties_180}, + {{0xEC0B4191, 0xAB0B, 0x4C66, {0x90, 0xB6}, {0xC6, 0x63, 0x7C, 0xDE, 0xBB, 0xAB}},guid_properties_181}, + {{0x660E04D6, 0x81AB, 0x4977, {0xA0, 0x9F}, {0x82, 0x31, 0x31, 0x13, 0xAB, 0x26}},guid_properties_182}, + {{0xDC54FD2E, 0x189D, 0x4871, {0xAA, 0x01}, {0x08, 0xC2, 0xF5, 0x7A, 0x4A, 0xBC}},guid_properties_183}, + {{0xCD102C9C, 0x5540, 0x4A88, {0xA6, 0xF6}, {0x64, 0xE4, 0x98, 0x1C, 0x8C, 0xD1}},guid_properties_184}, + {{0x1F856A9F, 0x6900, 0x4ABA, {0x95, 0x05}, {0x2D, 0x5F, 0x1B, 0x4D, 0x66, 0xCB}},guid_properties_185}, + {{0x90197CA7, 0xFD8F, 0x4E8C, {0x9D, 0xA3}, {0xB5, 0x7E, 0x1E, 0x60, 0x92, 0x95}},guid_properties_186}, + {{0xF334115E, 0xDA1B, 0x4509, {0x9B, 0x3D}, {0x11, 0x95, 0x04, 0xDC, 0x7A, 0xBB}},guid_properties_187}, + {{0xBF53D1C3, 0x49E0, 0x4F7F, {0x85, 0x67}, {0x5A, 0x82, 0x1D, 0x8A, 0xC5, 0x42}},guid_properties_188}, + {{0xC75FAA05, 0x96FD, 0x49E7, {0x9C, 0xB4}, {0x9F, 0x60, 0x10, 0x82, 0xD5, 0x53}},guid_properties_189}, + {{0x2E4B640D, 0x5019, 0x46D8, {0x88, 0x81}, {0x55, 0x41, 0x4C, 0xC5, 0xCA, 0xA0}},guid_properties_190}, + {{0x6B8B68F6, 0x200B, 0x47EA, {0x8D, 0x25}, {0xD8, 0x05, 0x0F, 0x57, 0x33, 0x9F}},guid_properties_191}, + {{0x2D152B40, 0xCA39, 0x40DB, {0xB2, 0xCC}, {0x57, 0x37, 0x25, 0xB2, 0xFE, 0xC5}},guid_properties_192}, + {{0x7268AF55, 0x1CE4, 0x4F6E, {0xA4, 0x1F}, {0xB6, 0xE4, 0xEF, 0x10, 0xE4, 0xA9}},guid_properties_193}, + {{0xD6304E01, 0xF8F5, 0x4F45, {0x8B, 0x15}, {0xD0, 0x24, 0xA6, 0x29, 0x67, 0x89}},guid_properties_194}, + {{0xA7AC77ED, 0xF8D7, 0x11CE, {0xA7, 0x98}, {0x00, 0x20, 0xF8, 0x00, 0x80, 0x25}},guid_properties_195}, + {{0x402B5934, 0xEC5A, 0x48C3, {0x93, 0xE6}, {0x85, 0xE8, 0x6A, 0x2D, 0x93, 0x4E}},guid_properties_196}, + {{0x9AEBAE7A, 0x9644, 0x487D, {0xA9, 0x2C}, {0x65, 0x75, 0x85, 0xED, 0x75, 0x1A}},guid_properties_197}, + {{0x63C25B20, 0x96BE, 0x488F, {0x87, 0x88}, {0xC0, 0x9C, 0x40, 0x7A, 0xD8, 0x12}},guid_properties_198}, + {{0x39A7F922, 0x477C, 0x48DE, {0x8B, 0xC8}, {0xB2, 0x84, 0x41, 0xE3, 0x42, 0xE3}},guid_properties_199}, + {{0x4776CAFA, 0xBCE4, 0x4CB1, {0xA2, 0x3E}, {0x26, 0x5E, 0x76, 0xD8, 0xEB, 0x11}},guid_properties_200}, + {{0xE3E0584C, 0xB788, 0x4A5A, {0xBB, 0x20}, {0x7F, 0x5A, 0x44, 0xC9, 0xAC, 0xDD}},guid_properties_201}, + {{0x95BEB1FC, 0x326D, 0x4644, {0xB3, 0x96}, {0xCD, 0x3E, 0xD9, 0x0E, 0x6D, 0xDF}},guid_properties_202}, + {{0xC0AC206A, 0x827E, 0x4650, {0x95, 0xAE}, {0x77, 0xE2, 0xBB, 0x74, 0xFC, 0xC9}},guid_properties_203}, +}; + +const struct full_propset_info *get_propset_info_with_guid( + const char *prop_name, + struct GUID *propset_guid) +{ + int i; + struct full_guid_propset *guid_propset = NULL; + const struct full_propset_info *result = NULL; + for (i = 0; i < ARRAY_SIZE(full_propertyset); i++) { + const struct full_propset_info *item = NULL; + guid_propset = &full_propertyset[i]; + item = guid_propset->prop_info; + while (item->id) { + if (strequal(prop_name, item->name)) { + *propset_guid = guid_propset->guid; + result = item; + break; + } + item++; + } + if (result) { + break; + } + } + return result; +} + +const struct full_propset_info *get_prop_info(const char *prop_name) +{ + const struct full_propset_info *result = NULL; + struct GUID guid; + result = get_propset_info_with_guid(prop_name, &guid); + return result; +} + +char *prop_from_fullprop(TALLOC_CTX *ctx, struct wsp_cfullpropspec *fullprop) +{ + int i; + char *result = NULL; + const struct full_propset_info *item = NULL; + bool search_by_id = (fullprop->ulkind == PRSPEC_PROPID); + + for (i = 0; i < ARRAY_SIZE(full_propertyset); i++) { + /* find propset */ + if (GUID_equal(&fullprop->guidpropset, + &full_propertyset[i].guid)) { + item = full_propertyset[i].prop_info; + break; + } + } + if (item) { + while (item->id) { + if (search_by_id) { + if( fullprop->name_or_id.prspec == item->id) { + result = talloc_strdup(ctx, item->name); + break; + } + } else if (strcmp(item->name, + fullprop->name_or_id.propname.vstring) + == 0) { + result = talloc_strdup(ctx, item->name); + break; + } + item++; + } + } + + if (!result) { + result = GUID_string(ctx, &fullprop->guidpropset); + + if (search_by_id) { + result = talloc_asprintf(result, "%s/%d", result, + fullprop->name_or_id.prspec); + } else { + result = talloc_asprintf(result, "%s/%s", result, + fullprop->name_or_id.propname.vstring); + } + } + return result; +} + +static const struct { + uint32_t id; + const char *name; +} typename_map[] = { + {VT_EMPTY, "Empty"}, + {VT_NULL, "Null"}, + {VT_I2, "VT_I2"}, + {VT_I4, "VT_I4"}, + {VT_I4, "VT_I4"}, + {VT_R4, "VT_R4"}, + {VT_R8, "VT_R8"}, + {VT_CY, "VT_CY"}, + {VT_DATE, "VT_DATE"}, + {VT_BSTR, "VT_BSTR"}, + {VT_I1, "VT_I1"}, + {VT_UI1, "VT_UI1"}, + {VT_UI2, "VT_UI2"}, + {VT_UI4, "VT_UI4"}, + {VT_I8, "VT_I8"}, + {VT_UI8, "VT_UI8"}, + {VT_INT, "VT_INT"}, + {VT_UINT, "VT_UINT"}, + {VT_ERROR, "VT_ERROR"}, + {VT_BOOL, "VT_BOOL"}, + {VT_VARIANT, "VT_VARIANT"}, + {VT_DECIMAL, "VT_DECIMAL"}, + {VT_FILETIME, "VT_FILETIME"}, + {VT_BLOB, "VT_BLOB"}, + {VT_BLOB_OBJECT, "VT_BLOB_OBJECT"}, + {VT_CLSID, "VT_CLSID"}, + {VT_LPSTR, "VT_LPSTR"}, + {VT_LPWSTR, "VT_LPWSTR"}, + {VT_COMPRESSED_LPWSTR, "VT_COMPRESSED_LPWSTR"}, +}; + +const char * get_vtype_name(uint32_t type) +{ + const char *type_name = NULL; + static char result_buf[255]; + int i; + uint32_t temp = type & ~(VT_VECTOR | VT_ARRAY); + for (i = 0; i < ARRAY_SIZE(typename_map); i++) { + if (temp == typename_map[i].id) { + type_name = typename_map[i].name; + break; + } + } + if (type & VT_VECTOR) { + snprintf(result_buf, sizeof(result_buf), "Vector | %s", type_name); + } else if (type & VT_ARRAY) { + snprintf(result_buf, sizeof(result_buf), "Array | %s", type_name); + } else { + snprintf(result_buf, sizeof(result_buf), "%s", type_name); + } + return result_buf; +} + +bool is_variable_size(uint16_t vtype) +{ + bool result; + switch(vtype) { + case VT_LPWSTR: + case VT_BSTR: + case VT_BLOB: + case VT_BLOB_OBJECT: + case VT_VARIANT: + result = true; + break; + default: + result = false; + break; + } + return result; +} + +const char *get_store_status(uint8_t status_byte) +{ + const char *result; + switch(status_byte) { + case 0: + result = "StoreStatusOk"; + break; + case 1: + result = "StoreStatusDeferred"; + break; + case 2: + result = "StoreStatusNull"; + break; + default: + result = "Unknown Status"; + break; + } + return result; +} + +void set_variant_lpwstr(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *vvalue, + const char *string_val) +{ + vvalue->vtype = VT_LPWSTR; + vvalue->vvalue.vt_lpwstr.value = talloc_strdup(ctx, string_val); +} + +void set_variant_i4(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *vvalue, + uint32_t val) +{ + vvalue->vtype = VT_I4; + vvalue->vvalue.vt_i4 = val; +} + +void set_variant_vt_bool(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *variant, + bool bval) +{ + variant->vtype = VT_BOOL; + variant->vvalue.vt_bool = bval; +} + +static void fill_int32_vec(TALLOC_CTX* ctx, + int32_t **pdest, + int32_t* ivector, uint32_t elems) +{ + int i; + int32_t *dest = talloc_zero_array(ctx, int32_t, elems); + for ( i = 0; i < elems; i++ ) { + dest[ i ] = ivector[ i ]; + } + *pdest = dest; +} + +void set_variant_i4_vector(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *variant, + int32_t* ivector, uint32_t elems) +{ + variant->vtype = VT_VECTOR | VT_I4; + variant->vvalue.vt_i4_vec.vvector_elements = elems; + fill_int32_vec(ctx, &variant->vvalue.vt_i4_vec.vvector_data, ivector, elems); +} + +static void fill_string_vec(TALLOC_CTX* ctx, + struct wsp_cbasestoragevariant *variant, + const char **strings, uint16_t elems) +{ + int i; + variant->vvalue.vt_lpwstr_v.vvector_elements = elems; + variant->vvalue.vt_lpwstr_v.vvector_data = talloc_zero_array(ctx, + struct vt_lpwstr, + elems); + + for( i = 0; i < elems; i++ ) { + variant->vvalue.vt_lpwstr_v.vvector_data[ i ].value = talloc_strdup(ctx, strings[ i ]); + } +} + +static void fill_bstr_vec(TALLOC_CTX *ctx, + struct vt_bstr **pvector, + const char **strings, uint16_t elems) +{ + int i; + struct vt_bstr *vdata = talloc_zero_array(ctx, struct vt_bstr, elems); + + for( i = 0; i < elems; i++ ) { + vdata [ i ].value = talloc_strdup(ctx, strings[ i ]); + } + *pvector = vdata; +} + +void set_variant_bstr(TALLOC_CTX *ctx, struct wsp_cbasestoragevariant *variant, + const char *string_val) +{ + variant->vtype = VT_BSTR; + variant->vvalue.vt_bstr.value = talloc_strdup(ctx, string_val); +} + +void set_variant_lpwstr_vector(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *variant, + const char **string_vals, uint32_t elems) +{ + variant->vtype = VT_LPWSTR | VT_VECTOR; + fill_string_vec(ctx, variant, string_vals, elems); +} + +void set_variant_array_bstr(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *variant, + const char **string_vals, uint16_t elems) +{ + variant->vtype = VT_BSTR | VT_ARRAY; + variant->vvalue.vt_bstr_array.cdims = 1; + variant->vvalue.vt_bstr_array.ffeatures = 0; + + variant->vvalue.vt_bstr_array.rgsabound = + talloc_zero_array(ctx, struct safearraybound, 1); + + variant->vvalue.vt_bstr_array.rgsabound[0].celements = elems; + variant->vvalue.vt_bstr_array.rgsabound[0].ilbound = 0; + variant->vvalue.vt_bstr_array.cbelements = 0; + fill_bstr_vec(ctx, &variant->vvalue.vt_bstr_array.vdata, + string_vals, elems); + /* + * if cbelements is the num bytes per elem it kindof means each + * string in the array must be the same size ? + */ + + if (elems >0) { + variant->vvalue.vt_bstr_array.cbelements = + strlen_m_term(variant->vvalue.vt_bstr_array.vdata[0].value)*2; + } +} + +/* create single dim array of vt_i4 */ +void set_variant_array_i4(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *variant, + int32_t *vals, uint16_t elems) +{ + /* #TODO see if we can combine with other set_variant_array methods */ + variant->vtype = VT_I4 | VT_ARRAY; + variant->vvalue.vt_i4_array.cdims = 1; + variant->vvalue.vt_i4_array.ffeatures = 0; + + variant->vvalue.vt_i4_array.rgsabound = + talloc_zero_array(ctx, struct safearraybound, 1); + + variant->vvalue.vt_i4_array.rgsabound[0].celements = elems; + variant->vvalue.vt_i4_array.rgsabound[0].ilbound = 0; + variant->vvalue.vt_i4_array.cbelements = sizeof(uint32_t); + fill_int32_vec(ctx, &variant->vvalue.vt_i4_array.vdata, vals, elems); +} + +const char *genmeth_to_string(uint32_t genmethod) +{ + const char *result; + switch (genmethod) { + case 0: + result = "equals"; + break; + case 1: + result = "starts with"; + break; + case 2: + result = "matches inflection"; + break; + default: + result = "ERROR, unknown generate method"; + break; + } + return result; +} + +bool is_operator(struct wsp_crestriction *restriction) { + bool result; + switch(restriction->ultype) { + case RTAND: + case RTOR: + case RTNOT: + result = true; + break; + default: + result = false; + break; + } + return result; +} + +const char *op_as_string(struct wsp_crestriction *restriction) +{ + const char *op = NULL; + if (is_operator(restriction)) { + switch(restriction->ultype) { + case RTAND: + op = " && "; + break; + case RTOR: + op = " || "; + break; + case RTNOT: + op = "!"; + break; + } + } else if (restriction->ultype == RTPROPERTY) { + struct wsp_cpropertyrestriction *prop_restr = + &restriction->restriction.cpropertyrestriction; + switch (prop_restr->relop & 0XF) { + case PREQ: + op = "="; + break; + case PRNE: + op = "!="; + break; + case PRGE: + op = ">="; + break; + case PRLE: + op = "<="; + break; + case PRLT: + op = "<"; + break; + case PRGT: + op = ">"; + break; + default: + break; + } + } else if (restriction->ultype == RTCONTENT) { + struct wsp_ccontentrestriction *content = NULL; + content = &restriction->restriction.ccontentrestriction; + op = genmeth_to_string(content->ulgeneratemethod); + } else if (restriction->ultype == RTNATLANGUAGE) { + op = "="; + } + return op; +} + +struct wsp_cfullpropspec *get_full_prop(struct wsp_crestriction *restriction) +{ + struct wsp_cfullpropspec *result; + switch (restriction->ultype) { + case RTPROPERTY: + result = &restriction->restriction.cpropertyrestriction.property; + break; + case RTCONTENT: + result = &restriction->restriction.ccontentrestriction.property; + break; + case RTNATLANGUAGE: + result = &restriction->restriction.cnatlanguagerestriction.property; + break; + default: + result = NULL; + break; + } + return result; +} + +const char *variant_as_string(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *value, bool quote) +{ + const char* result = NULL; + switch(value->vtype) { + case VT_I4: + case VT_UI4: + case VT_INT: + case VT_UINT: + case VT_I2: + case VT_UI2: + result = talloc_asprintf(ctx, "%d", + value->vvalue.vt_i4); + break; + case VT_I8: + case VT_UI8: + case VT_R8: + case VT_CY: + case VT_DATE: + case VT_FILETIME: { + uint64_t val; + wsp_hyper_to_uint64(&value->vvalue.vt_ui8, &val); + if (value->vtype == VT_I8) { + result = talloc_asprintf(ctx, "%" PRId64, + val); + } else { + result = talloc_asprintf(ctx, "%" PRIu64, + val); + } + break; + } + case VT_LPWSTR: + result = talloc_asprintf(ctx, "%s%s%s", + quote ? "\'" : "", + value->vvalue.vt_lpwstr.value, + quote ? "\'" : ""); + break; + case VT_LPWSTR | VT_VECTOR: { + int num_elems = + value->vvalue.vt_lpwstr_v.vvector_elements; + int i; + for(i = 0; i < num_elems; i++) { + struct vt_lpwstr_vec *vec; + const char *val; + vec = &value->vvalue.vt_lpwstr_v; + val = vec->vvector_data[i].value; + result = + talloc_asprintf(ctx, + "%s%s%s%s%s", + result ? result : "", + i ? "," : "", + quote ? "\'" : "", + val, + quote ? "\'" : ""); + } + break; + } + default: + DBG_INFO("#FIXME unsupported type 0x%x\n", + value->vtype); + break; + } + return result; +} + +static NTSTATUS restriction_node_to_string(TALLOC_CTX *ctx, + struct wsp_crestriction *restriction, + const char **str_result) +{ + const char *result = NULL; + struct wsp_cfullpropspec *full_prop = get_full_prop(restriction); + const char *op_str = op_as_string(restriction); + const char *propname = NULL; + const char *value = NULL; + NTSTATUS status = NT_STATUS_OK; + if (is_operator(restriction)) { + result = talloc_strdup(ctx, op_str); + goto out; + } + + if (restriction->ultype == RTPROPERTY + || restriction->ultype == RTCONTENT + || restriction->ultype == RTNATLANGUAGE) { + if (full_prop) { + propname = prop_from_fullprop(ctx, full_prop); + } + if (propname == NULL) { + DBG_ERR("Unknown propname\n"); + status = NT_STATUS_UNSUCCESSFUL; + goto out; + } + } + if (op_str == NULL) { + DBG_WARNING("Unknow operation for prop %s\n", propname); + } + switch(restriction->ultype) { + case RTCONTENT: { + struct wsp_ccontentrestriction *content = NULL; + content = + &restriction->restriction.ccontentrestriction; + value = talloc_strdup(ctx, content->pwcsphrase); + result = talloc_asprintf(ctx, "RTCONTENT %s %s %s", propname, op_str, value); + break; + } + case RTPROPERTY: { + struct wsp_cpropertyrestriction *prop = + &restriction->restriction.cpropertyrestriction; + struct wsp_cbasestoragevariant *variant = &prop->prval; + value = variant_as_string(ctx, variant, true); + result = talloc_asprintf(ctx, "RTPROPERTY %s %s %s", propname, op_str, value); + break; + } + case RTNATLANGUAGE: { + struct wsp_cnatlanguagerestriction *cnat = + &restriction->restriction.cnatlanguagerestriction; + result = talloc_asprintf(ctx, + "RTNATLANGUAGE %s %s %s", + propname, + op_str, + cnat->pwcsphrase); + + break; + } + case RTCOERCE_ABSOLUTE: { + struct wsp_crestriction *child_restrict = + restriction->restriction.ccoercionrestriction_abs.childres; + result = raw_restriction_to_string(ctx, child_restrict); + if (!result) { + status = NT_STATUS_UNSUCCESSFUL; + } + break; + } + case RTREUSEWHERE: { + uint32_t id = + restriction->restriction.reusewhere.whereid; + result = talloc_asprintf(ctx, + "insert expression for WHEREID = %d", + id); + + break; + } + default: + DBG_ERR("## unknown type 0x%x\n", restriction->ultype); + status = NT_STATUS_INVALID_PARAMETER; + break; + } +out: + *str_result = result; + return status; +} + +static NTSTATUS infix_restriction(TALLOC_CTX *ctx, + struct wsp_crestriction *restriction, + const char **str_result) +{ + const char *tmp = *str_result; + const char *token = NULL; + struct wsp_crestriction *left = NULL; + struct wsp_crestriction *right = NULL; + NTSTATUS status; + if (!restriction) { + status = NT_STATUS_OK; + goto out; + } + if (is_operator(restriction)) { + if (restriction->ultype == RTAND + || restriction->ultype == RTOR) { + struct wsp_cnoderestriction *cnodes = + &restriction->restriction.cnoderestriction; + if (cnodes->cnode) { + left = &cnodes->panode[0]; + if (cnodes->cnode > 1) { + right = &cnodes->panode[1]; + } + } + } else { + right = restriction->restriction.restriction.restriction; + } + tmp = talloc_asprintf(ctx, "%s(", tmp ? tmp : ""); + } + status = infix_restriction(ctx, left, &tmp); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + status = restriction_node_to_string(ctx, restriction, &token); + + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + tmp = talloc_asprintf(ctx, "%s%s", tmp ? tmp : "", token); + + status = infix_restriction(ctx, right, &tmp); + + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + if (is_operator(restriction)) { + tmp = talloc_asprintf(ctx, "%s)",tmp); + } + *str_result = tmp; +out: + return status; +} + +const char *raw_restriction_to_string(TALLOC_CTX *ctx, + struct wsp_crestriction *restriction) +{ + const char *result = NULL; + infix_restriction(ctx, restriction, &result); + return result; +} diff --git a/librpc/rpc/wsp_helper.h b/librpc/rpc/wsp_helper.h index 76b5156..01efb62 100644 --- a/librpc/rpc/wsp_helper.h +++ b/librpc/rpc/wsp_helper.h @@ -22,10 +22,69 @@ #define __LIBRPC_WSP_HELPER_H__ struct safearraybound; +struct wsp_cfullpropspec; +struct wsp_cpmgetrowsin; +struct wsp_cpmgetrowsout; +struct wsp_cpmsetbindingsin; +struct wsp_cbasestoragevariant; +struct wsp_crestriction; struct wsp_hyper; - +struct GUID; uint32_t calc_array_size(struct safearraybound *bounds, uint32_t ndims); + +struct full_propset_info { + uint32_t id; + const char *name; + uint16_t vtype; + bool extra_info; + bool in_inverted_index; + bool is_column; + bool can_col_be_indexed; + uint16_t max_size; +}; + +char *prop_from_fullprop(TALLOC_CTX *ctx, struct wsp_cfullpropspec *fullprop); +const struct full_propset_info *get_prop_info(const char *prop_name); +const struct full_propset_info *get_propset_info_with_guid( + const char *prop_name, + struct GUID *guid); +const char * get_vtype_name(uint32_t type); +bool is_variable_size(uint16_t vtype); void uint64_to_wsp_hyper(uint64_t src, struct wsp_hyper *dest); void wsp_hyper_to_uint64(struct wsp_hyper *src, uint64_t *dest); +const char *get_store_status(uint8_t status_byte); + +bool is_operator(struct wsp_crestriction *restriction); +const char *op_as_string(struct wsp_crestriction *restriction); +const char *raw_restriction_to_string(TALLOC_CTX *ctx, + struct wsp_crestriction *restriction); +struct wsp_cfullpropspec *get_full_prop(struct wsp_crestriction *restriction); +const char *genmeth_to_string(uint32_t genmethod); +const char *variant_as_string(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *value, + bool quote); +void set_variant_lpwstr(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *vvalue, + const char *string_val); +void set_variant_i4(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *vvalue, + uint32_t val); +void set_variant_vt_bool(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *variant, + bool bval); +void set_variant_bstr(TALLOC_CTX *ctx, struct wsp_cbasestoragevariant *variant, + const char *string_val); +void set_variant_lpwstr_vector(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *variant, + const char **string_vals, uint32_t elems); +void set_variant_array_bstr(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *variant, + const char **string_vals, uint16_t elems); +void set_variant_i4_vector(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *variant, + int32_t* ivector, uint32_t elems); +void set_variant_array_i4(TALLOC_CTX *ctx, + struct wsp_cbasestoragevariant *variant, + int32_t *vals, uint16_t elems); #endif // __LIBRPC_WSP_HELPER_H__ -- 2.10.2 >From 0a7e6246e581ebe808b6be44b5d1910238367a2c Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 29 Jun 2016 11:29:54 +0100 Subject: [PATCH 09/10] s4/libcli: Add simple client api for wsp client code. Signed-off-by: Noel Power --- source4/libcli/wscript_build | 5 + source4/libcli/wsp/wsp_aqs.c | 800 ++++++++++++ source4/libcli/wsp/wsp_aqs.h | 166 +++ source4/libcli/wsp/wsp_aqs_lexer.c | 2305 ++++++++++++++++++++++++++++++++++ source4/libcli/wsp/wsp_aqs_lexer.h | 346 ++++++ source4/libcli/wsp/wsp_aqs_lexer.l | 150 +++ source4/libcli/wsp/wsp_aqs_parser.c | 2319 +++++++++++++++++++++++++++++++++++ source4/libcli/wsp/wsp_aqs_parser.h | 158 +++ source4/libcli/wsp/wsp_aqs_parser.y | 425 +++++++ source4/libcli/wsp/wsp_cli.c | 1794 +++++++++++++++++++++++++++ source4/libcli/wsp/wsp_cli.h | 110 ++ 11 files changed, 8578 insertions(+) create mode 100644 source4/libcli/wsp/wsp_aqs.c create mode 100644 source4/libcli/wsp/wsp_aqs.h create mode 100644 source4/libcli/wsp/wsp_aqs_lexer.c create mode 100644 source4/libcli/wsp/wsp_aqs_lexer.h create mode 100644 source4/libcli/wsp/wsp_aqs_lexer.l create mode 100644 source4/libcli/wsp/wsp_aqs_parser.c create mode 100644 source4/libcli/wsp/wsp_aqs_parser.h create mode 100644 source4/libcli/wsp/wsp_aqs_parser.y create mode 100644 source4/libcli/wsp/wsp_cli.c create mode 100644 source4/libcli/wsp/wsp_cli.h diff --git a/source4/libcli/wscript_build b/source4/libcli/wscript_build index 38a8f4e..05056db 100755 --- a/source4/libcli/wscript_build +++ b/source4/libcli/wscript_build @@ -8,6 +8,11 @@ bld.SAMBA_SUBSYSTEM('LIBSAMBA_TSOCKET', public_deps='LIBTSOCKET tevent-util' ) +bld.SAMBA_SUBSYSTEM('LIBSAMBA_WSP', + source='wsp/wsp_cli.c wsp/wsp_cli.c wsp/wsp_aqs.c wsp/wsp_aqs_parser.c wsp/wsp_aqs_lexer.c', + public_deps='tevent-util', + enabled=bld.env.with_wsp + ) bld.SAMBA_SUBSYSTEM('LIBCLI_LSA', source='util/clilsa.c', diff --git a/source4/libcli/wsp/wsp_aqs.c b/source4/libcli/wsp/wsp_aqs.c new file mode 100644 index 0000000..ef6cc7c --- /dev/null +++ b/source4/libcli/wsp/wsp_aqs.c @@ -0,0 +1,800 @@ +/* + * Window Search Service + * + * Copyright (c) 2016 Noel Power + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" +#include "libcli/wsp/wsp_aqs.h" +#include "libcli/wsp/wsp_aqs_parser.h" +#include "libcli/wsp/wsp_aqs_lexer.h" +#include "librpc/rpc/wsp_helper.h" +#include +#include + +int yyparse(t_select_stmt **select, yyscan_t scanner); + +static void reverse_cols(t_select_stmt *select) +{ + int num_elems, fwd, rev; + char **cols; + + + if (!select->cols) { + return; + } + num_elems = select->cols->num_cols; + cols = select->cols->cols; + + for(fwd = 0, rev = num_elems - 1; fwd <= rev; fwd++, rev--) { + char * tmp = cols[rev]; + cols[rev] = cols[fwd]; + cols[fwd] = tmp; + } + +} + +t_select_stmt *get_wsp_sql_tree(const char *expr) +{ + t_select_stmt *select = NULL; + yyscan_t scanner; + YY_BUFFER_STATE state; + + if (yylex_init(&scanner)) { + printf("couldn't initialize\n"); + return NULL; + } + + state = yy_scan_string(expr, scanner); + + if (yyparse(&select, scanner)) { + printf("some parse error\n"); + return NULL; + } + /* + * parsed columns are in reverse order to how they are specified + * in the AQS like statement, reverse them again to correct this. + */ + reverse_cols(select); + + yy_delete_buffer(state, scanner); + + yylex_destroy(scanner); + + return select; +} + + +t_col_list *create_cols(TALLOC_CTX *ctx, const char *col, t_col_list *append_list) +{ + t_col_list *cols = append_list; + if (!get_prop_info(col)) { + DBG_ERR("Unknown property %s\n", col); + return NULL; + } + if (cols == NULL) { + cols = talloc_zero(ctx, t_col_list); + cols->num_cols = 0; + cols->cols = NULL; + printf("returning new cols %p with item %s\n", cols, col); + } + if (col) { + int old_index = cols->num_cols; + if (old_index == 0) { + cols->cols = talloc_array(cols, char*, 1); + } else { + cols->cols = (char **)talloc_realloc(cols, cols->cols, char*, old_index + 1); + } + if (!cols->cols) { + return NULL; /* can we create a parser error here */ + } + cols->num_cols++; + cols->cols[old_index] = talloc_strdup(cols, col); + } + return cols; +} + +t_select_stmt *create_select(TALLOC_CTX *ctx, t_col_list *cols, t_query *where) +{ + t_select_stmt *result = talloc_zero(ctx, t_select_stmt); + result->cols = cols; + result->where = where; + return result; +} + +t_basic_restr *create_basic_restr(TALLOC_CTX *ctx, + uint32_t prop_type, + t_optype op, + t_value_holder *values) +{ + t_basic_restr *result = talloc_zero(ctx, t_basic_restr); + result->prop_type = prop_type; + result->op = op; + if (values->type == VALUE_RANGE) { + t_restr *left_node; + t_restr *right_node; + t_basic_restr *left_val; + t_basic_restr *right_val; + if (op != eEQ) { + DBG_ERR("Unsupported operation %d\n", op); + TALLOC_FREE(result); + goto out; + } + + if (values->value.value_range->lower == NULL) { + DBG_ERR("range lower limit doesn't exist\n"); + TALLOC_FREE(result); + goto out; + } + /* + * detect special case where upper range doesn't exist + * and convert to a propery value. (this won't happen from + * the cmdline directly but only as a result of a range + * created 'specially' in code, e.g. special gigantic size + * range. + */ + if (values->value.value_range->upper == NULL) { + result->op = eGE; + result->values = values->value.value_range->lower; + goto out; + } + result->values = talloc_zero(result, t_value_holder); + /* + * try create a restriction tree (>=lower AND values, + prop_type, + eGE, + values->value.value_range->lower); + + right_val = create_basic_restr(result->values, + prop_type, + eLT, + values->value.value_range->upper); + + if (!left_val || !right_val) { + DBG_ERR("Failed creating basic_restriction values " + "for range\n"); + TALLOC_FREE(result); + goto out; + } + + left_node = create_restr(result->values, eVALUE, NULL, NULL, left_val); + right_node = create_restr(result->values, eVALUE, NULL, NULL, right_val); + + + if (!left_node || !right_node) { + DBG_ERR("Failed creating restr nodes for range\n"); + TALLOC_FREE(result); + goto out; + } + result->values->type = RESTR; + result->values->value.restr_tree = create_restr(result->values, + eAND, + left_node, + right_node, + NULL); + if (!result->values->value.restr_tree) { + DBG_ERR("Failed creating restr tree for range\n"); + TALLOC_FREE(result); + goto out; + } + } else { + result->values = values; + } +out: + return result; +} + +/* + * The parser reads numbers as VT_UI8, booleans as VT_BOOL and strings as + * VT_LPWSTR + */ +typedef bool (*conv_func) (TALLOC_CTX *ctx, t_value_holder *src, + struct wsp_cbasestoragevariant *dest, + uint16_t dest_type); + +/* + * default convertor #TODO probabaly should cater for detecting over/underrun + * depending on the dest_type we are narrowing to + */ +static bool default_convertor(TALLOC_CTX *ctx, + t_value_holder *src, + struct wsp_cbasestoragevariant *dest, + uint16_t dest_type) +{ + if (src->type != NUMBER) { + return false; + } + uint64_to_wsp_hyper(src->value.number, &dest->vvalue.vt_ui8); + dest->vtype = dest_type; + return true; +} + +static bool convert_string_to_lpwstr_v(TALLOC_CTX *ctx, + t_value_holder *src, + struct wsp_cbasestoragevariant *dest, + uint16_t dest_type) +{ + const char *str = src->value.string; + set_variant_lpwstr_vector(ctx, dest, &str, 1); + return true; +} + +static bool convert_string_to_lpwstr(TALLOC_CTX *ctx, + t_value_holder *src, + struct wsp_cbasestoragevariant *dest, + uint16_t dest_type) +{ + const char *str = src->value.string; + set_variant_lpwstr(ctx, dest, str); + return true; +} + +static bool convert_bool_to_lpwstr(TALLOC_CTX *ctx, + t_value_holder *src, + struct wsp_cbasestoragevariant *dest, + uint16_t dest_type) +{ + set_variant_lpwstr( + ctx, + dest, + src->value.boolean ? "true": "false"); + return true; +} + +static bool convert_string_to_filetime(TALLOC_CTX *ctx, + t_value_holder *src, + struct wsp_cbasestoragevariant *dest, + uint16_t dest_type) +{ + + static const char *fmts[] = { + "%FT%TZ", + "%FT%T", + "%F %T", + "%F %R", + "%F", + }; + struct tm tm; + time_t timeval; + int i; + ZERO_STRUCT(tm); + + for (i = 0; i < ARRAY_SIZE(fmts); i++) { + if (strptime(src->value.string, fmts[i], &tm)) { + timeval = timegm(&tm); + break; + } + } + + if (timeval) { + uint64_t filetime; + struct wsp_hyper *p_hyper = &dest->vvalue.vt_filetime; + filetime = ((timeval * 10000000) + 116444736000000000); + dest->vtype = VT_FILETIME; + uint64_to_wsp_hyper(filetime, p_hyper); + return true; + } + return false; +} + +const struct { + uint16_t src_vtype; + uint16_t dest_vtype; + conv_func convert_type; +} type_conv_map[] = { + {NUMBER, VT_I8, default_convertor}, + {NUMBER, VT_UI8, default_convertor}, + {NUMBER, VT_INT, default_convertor}, + {NUMBER, VT_UINT, default_convertor}, + {NUMBER, VT_I4, default_convertor}, + {NUMBER, VT_UI4, default_convertor}, + {NUMBER, VT_I2, default_convertor}, + {NUMBER, VT_UI2, default_convertor}, + {NUMBER, VT_BOOL, default_convertor}, + {NUMBER, VT_FILETIME, default_convertor}, + {NUMBER, VT_BOOL, default_convertor}, + {BOOL, VT_LPWSTR, convert_bool_to_lpwstr}, + {STRING, VT_LPWSTR, convert_string_to_lpwstr}, + {STRING, VT_LPWSTR | VT_VECTOR, convert_string_to_lpwstr_v}, + {STRING, VT_FILETIME, convert_string_to_filetime}, +}; + +static bool process_prop_value(TALLOC_CTX *ctx, + const struct full_propset_info *prop_info, + t_value_holder *node_value, + struct wsp_cbasestoragevariant *prop_value) +{ + int i; + + /* coerce type as required */ + for (i = 0; i < ARRAY_SIZE(type_conv_map); i++ ) { + if (type_conv_map[i].src_vtype == node_value->type && + type_conv_map[i].dest_vtype == prop_info->vtype) { + type_conv_map[i].convert_type(ctx, + node_value, + prop_value, + prop_info->vtype); + return true; + } + } + return false; +} + +t_basic_query *create_basic_query(TALLOC_CTX *ctx, const char *propname, t_basic_restr *restr) +{ + t_basic_query *result = talloc_zero(ctx, t_basic_query); + result->prop = talloc_strdup(result, propname); + result->prop_info = get_propset_info_with_guid(propname, &result->guid); + + if (!result->prop_info) { + DBG_ERR("Unknown property %s\n",propname); + TALLOC_FREE(result); + goto out; + } + result->basic_restriction = restr; +out: + return result; +} + +static struct wsp_crestriction *create_restriction(TALLOC_CTX *ctx, + t_basic_query *query) +{ + struct wsp_crestriction *crestriction = + talloc_zero(ctx, struct wsp_crestriction); + struct wsp_cfullpropspec *prop; + t_basic_restr *restr = query->basic_restriction; + t_value_holder *src = restr->values; + if (restr->prop_type == RTNONE) { + /* shouldn't end up here */ + DBG_ERR("Unexpected t_basic_restr type\n"); + goto done; + } + + crestriction->weight = 1000; + + if (restr->prop_type == RTCONTENT) { + struct wsp_ccontentrestriction *content = NULL; + crestriction->ultype = RTCONTENT; + if (src->type != STRING) { + DBG_ERR("expected string value for %s\n", + query->prop); + TALLOC_FREE(crestriction); + goto done; + } + content = &crestriction->restriction.ccontentrestriction; + content->pwcsphrase = src->value.string; + content->cc = strlen(src->value.string); + /* #TODO we might be able to generate the lcid from environ */ + content->lcid = 0x00000409; + if (restr->op == eEQUALS) { + content->ulgeneratemethod = 0; + } else { + content->ulgeneratemethod = 1; + } + + prop = &content->property; + } else if (restr->prop_type == RTPROPERTY) { + struct wsp_cbasestoragevariant *dest = + &crestriction->restriction.cpropertyrestriction.prval; + crestriction->ultype = RTPROPERTY; + if (!process_prop_value(ctx, query->prop_info, src, dest)) { + DBG_ERR("Failed to process value for property %s\n", + query->prop); + TALLOC_FREE(crestriction); + goto done; + } + crestriction->restriction.cpropertyrestriction.relop = + restr->op; + prop = &crestriction->restriction.cpropertyrestriction.property; + } else { + TALLOC_FREE(crestriction); + goto done; + } + prop->guidpropset = query->guid; + prop->ulkind = PRSPEC_PROPID; + prop->name_or_id.prspec = query->prop_info->id; +done: + return crestriction; +} + +/* expands restr_node into a tree of t_query nodes */ +static void build_query(TALLOC_CTX *ctx, t_query *node, t_restr *restr_node, + const char* prop) +{ + if (!node) { + return; + } + if (!restr_node) { + return; + } + + node->type = restr_node->type; + + if (restr_node->left) { + node->left = talloc_zero(ctx, t_query); + build_query(ctx, node->left, restr_node->left, prop); + } + + if (restr_node->right) { + node->right = talloc_zero(ctx, t_query); + build_query(ctx, node->right, restr_node->right, prop); + } + + if (restr_node->type == eVALUE) { + node->restriction = + create_restriction(ctx, + create_basic_query(ctx, + prop, + restr_node->basic_restr)); + } +} + +t_query *create_query_node(TALLOC_CTX *ctx, t_nodetype op, t_query *left, t_query *right, t_basic_query *value) +{ + t_query *result = talloc_zero(ctx, t_query); + if (result == NULL) { + return result; + } + result->type = op; + result->left = left; + result->right = right; + if (op == eVALUE) { + t_basic_restr *restr = value->basic_restriction; + /* expand restr node */ + if (restr->values->type == RESTR) { + build_query(ctx, + result, + restr->values->value.restr_tree, + value->prop); + } else { + result->restriction = + create_restriction(ctx, value); + if (!result->restriction) { + TALLOC_FREE(result); + } + } + } + return result; +} + +t_restr *create_restr(TALLOC_CTX *ctx, t_nodetype op, t_restr *left, t_restr *right, t_basic_restr *value) +{ + t_restr *result = talloc_zero(ctx, t_restr); + if (result == NULL) { + return result; + } + result->type = op; + result->right = right; + result->left = left; + result->basic_restr = value; + return result; +} + +t_value_holder *create_string_val(TALLOC_CTX* ctx, const char *text) +{ + t_value_holder *result = + talloc_zero(ctx, t_value_holder); + result->value.string = text; + result->type = STRING; + return result; +} + +t_value_holder *create_num_val(TALLOC_CTX* ctx, int64_t val) +{ + t_value_holder *result = + talloc_zero(ctx, t_value_holder); + + result->type = NUMBER; + result->value.number = val; + return result; +} + +t_value_holder *create_bool_val(TALLOC_CTX* ctx, bool val) +{ + t_value_holder *result = + talloc_zero(ctx, t_value_holder); + + result->type = BOOL; + result->value.boolean = val; + return result; +} + +t_value_holder *create_value_range(TALLOC_CTX* ctx, + t_value_holder *left, + t_value_holder *right) +{ + t_value_holder *result = + talloc_zero(ctx, t_value_holder); + result->type = VALUE_RANGE; + result->value.value_range = talloc_zero(result, struct value_range); + if (!result->value.value_range) { + TALLOC_FREE(result); + goto out; + } + result->value.value_range->lower = left; + result->value.value_range->upper = right; +out: + return result; +} + +static void zero_time(struct tm *tm) +{ + tm->tm_hour = 0; + tm->tm_min = 0; + tm->tm_sec = 0; +} + +typedef bool (*daterange_func) (TALLOC_CTX *ctx, uint64_t *date1, + uint64_t *date2); + + +static bool create_date_range(TALLOC_CTX *ctx, uint64_t *date1, + uint64_t *date2, + int32_t lower_mday_adj, + int32_t lower_mon_adj, + int32_t upper_mday_adj, + int32_t upper_mon_adj) +{ + struct tm tm_now; + time_t now; + + struct tm tm_tmp; + time_t lower; + time_t upper; + + time(&now); + gmtime_r(&now, &tm_now); + + tm_tmp = tm_now; + zero_time(&tm_tmp); + tm_tmp.tm_mday += lower_mday_adj; + tm_tmp.tm_mon += lower_mon_adj; + lower = mktime(&tm_tmp); + tm_tmp = tm_now; + zero_time(&tm_tmp); + tm_tmp.tm_mday += upper_mday_adj; + tm_tmp.tm_mon += upper_mon_adj; + upper = mktime(&tm_tmp); + *date1 = ((lower * 10000000) + 116444736000000000); + *date2 = ((upper * 10000000) + 116444736000000000); + return true; +} + +static void get_now_tm(struct tm *tm_now) +{ + time_t now; + time(&now); + gmtime_r(&now, tm_now); +} + +static bool create_thismonth_range(TALLOC_CTX *ctx, uint64_t *date1, + uint64_t *date2) +{ + struct tm tm_now; + int32_t firstofmonth_adj; + + get_now_tm(&tm_now); + firstofmonth_adj = 1 - tm_now.tm_mday; + return create_date_range(ctx, date1, + date2, firstofmonth_adj, + 0, firstofmonth_adj, 1); +} + +static bool create_lastyear_range(TALLOC_CTX *ctx, uint64_t *date1, + uint64_t *date2) +{ + struct tm tm_now; + int32_t firstofmonth_adj; + int32_t january_adj; + get_now_tm(&tm_now); + + firstofmonth_adj = 1 - tm_now.tm_mday; + january_adj = -tm_now.tm_mon; + return create_date_range(ctx, date1, + date2, firstofmonth_adj, + january_adj - 12, firstofmonth_adj, january_adj); +} + +static bool create_thisyear_range(TALLOC_CTX *ctx, uint64_t *date1, + uint64_t *date2) +{ + struct tm tm_now; + int32_t firstofmonth_adj; + int32_t january_adj; + + get_now_tm(&tm_now); + + firstofmonth_adj = 1 - tm_now.tm_mday; + january_adj = -tm_now.tm_mon; + return create_date_range(ctx, date1, + date2, firstofmonth_adj, + january_adj, firstofmonth_adj, january_adj + 12); +} + +static bool create_lastmonth_range(TALLOC_CTX *ctx, uint64_t *date1, + uint64_t *date2) +{ + struct tm tm_now; + int32_t firstofmonth_adj; + get_now_tm(&tm_now); + + firstofmonth_adj = 1 - tm_now.tm_mday; + return create_date_range(ctx, date1, + date2, firstofmonth_adj, + -1, firstofmonth_adj, 0); +} + +static bool create_today_range(TALLOC_CTX *ctx, uint64_t *date1, + uint64_t *date2) +{ + return create_date_range(ctx, date1, + date2, 0, 0, 1, 0); +} + +static bool create_yesterday_range(TALLOC_CTX *ctx, uint64_t *date1, + uint64_t *date2) +{ + return create_date_range(ctx, date1, + date2, -1, 0, 0, 0); +} + +static bool create_thisweek_range(TALLOC_CTX *ctx, uint64_t *date1, + uint64_t *date2) +{ + struct tm tm_now; + time_t now; + int32_t startofweek_adj; + time(&now); + gmtime_r(&now, &tm_now); + if (tm_now.tm_wday) { + startofweek_adj = 1 - tm_now.tm_wday; + } else { + startofweek_adj = -6; + } + /*lower will be the start of this week*/ + return create_date_range(ctx, date1, + date2, startofweek_adj, + 0, startofweek_adj + 7, 0); +} + +static bool create_lastweek_range(TALLOC_CTX *ctx, uint64_t *date1, + uint64_t *date2) +{ + struct tm tm_now; + time_t now; + int32_t startofweek_adj; + time(&now); + gmtime_r(&now, &tm_now); + if (tm_now.tm_wday) { + startofweek_adj = 1 - tm_now.tm_wday; + } else { + startofweek_adj = -6; + } + /*upper will be the start of this week*/ + return create_date_range(ctx, date1, + date2, startofweek_adj - 7, + 0,startofweek_adj, 0); +} + +t_value_holder *create_date_range_shortcut(TALLOC_CTX *ctx, + daterange_type daterange) +{ + int i; + static const struct { + daterange_type range; + daterange_func create_fn; + } date_conv_map[] = { + {eYESTERDAY, create_yesterday_range}, + {eTODAY, create_today_range}, + {eTHISMONTH, create_thismonth_range}, + {eLASTMONTH, create_lastmonth_range}, + {eTHISWEEK, create_thisweek_range}, + {eLASTWEEK, create_lastweek_range}, + {eTHISYEAR, create_thisyear_range}, + {eLASTYEAR, create_lastyear_range}, + }; + t_value_holder *result = NULL; + t_value_holder *lower = talloc_zero(ctx, t_value_holder); + t_value_holder *upper = talloc_zero(ctx, t_value_holder); + result = create_value_range(result, lower, upper); + + if (result == NULL || lower == NULL || upper == NULL) { + TALLOC_FREE(result); + goto out; + } + + lower->type = NUMBER; + upper->type = NUMBER; + + result->value.value_range->lower = lower; + result->value.value_range->upper = upper; + + for (i = 0; i < ARRAY_SIZE(date_conv_map); i++) { + if (date_conv_map[i].range == daterange) { + if (!date_conv_map[i].create_fn(result, + &lower->value.number, + &upper->value.number)) { + TALLOC_FREE(result); + break; + } + break; + } + } +out: + return result; +} + +t_value_holder *create_size_range_shortcut(TALLOC_CTX *ctx, + sizerange_type sizerange) +{ + static const struct { + sizerange_type range; + uint32_t lower; + uint32_t upper; + } sizes[] = { + {eEMPTY, 0x0, 0x1}, + {eTINY, 0x1, 0x2801}, + {eSMALL, 0x2801, 0x19001}, + {eMEDIUM, 0x19001, 0x100001}, + {eLARGE, 0x100001, 0x10000001}, + {eHUGE, 0x10000001, 0x80000001}, + {eGIGANTIC, 0x80000001, 0} /* special case not a range */ + }; + int i; + t_value_holder *result = NULL; + uint32_t lower_size; + uint32_t upper_size; + bool rangefound = false; + t_value_holder *left = NULL; + t_value_holder *right = NULL; + for (i = 0; i < ARRAY_SIZE(sizes); i++) { + if (sizes[i].range == sizerange) { + result = talloc_zero(ctx, t_value_holder); + lower_size = sizes[i].lower; + upper_size = sizes[i].upper; + rangefound = true; + break; + } + } + + if (!rangefound) { + return NULL; + } + + left = talloc_zero(ctx, t_value_holder); + + if (left == NULL) { + return NULL; + } + + left->type = NUMBER; + left->value.number = lower_size; + + if (upper_size) { + right = talloc_zero(ctx, t_value_holder); + if (right == NULL) { + return NULL; + } + right->type = NUMBER; + right->value.number = upper_size; + } + + result = create_value_range(ctx, left, right); + return result; +} diff --git a/source4/libcli/wsp/wsp_aqs.h b/source4/libcli/wsp/wsp_aqs.h new file mode 100644 index 0000000..f8ffc63 --- /dev/null +++ b/source4/libcli/wsp/wsp_aqs.h @@ -0,0 +1,166 @@ +/* + * Window Search Service + * + * Copyright (c) 2016 Noel Power + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef __WSP_SQL_H__ +#define __WSP_SQL_H__ +#include "librpc/gen_ndr/wsp.h" + +typedef enum nodetype +{ + eAND, + eOR, + eNOT, + eVALUE, +} t_nodetype; + +typedef enum op +{ + eLT = PRLT, + eLE = PRLE, + eGT = PRGT, + eGE = PRGE, + eEQ = PREQ, + eNE = PRNE, + eSTARTSWITH, + eEQUALS, + /* + * eMATCHES, + * + * not sure we can express the above in the grammer without + * some custom operator :/ + */ +} t_optype; + +struct restr; + +typedef enum { + NUMBER, + STRING, + BOOL, + RESTR, + VALUE_RANGE, +} value_type; + +typedef enum { + eTODAY, + eYESTERDAY, + eLASTWEEK, + eTHISWEEK, + eTHISMONTH, + eLASTMONTH, + eTHISYEAR, + eLASTYEAR, +} daterange_type; + +typedef enum { + eEMPTY, + eTINY, + eSMALL, + eMEDIUM, + eLARGE, + eHUGE, + eGIGANTIC, +} sizerange_type; + +struct value_range; + +typedef struct { + value_type type; + union { + bool boolean; + const char *string; + uint64_t number; + struct restr *restr_tree; + struct value_range *value_range; + } value; +} t_value_holder; + +struct value_range +{ + t_value_holder *lower; + t_value_holder *upper; +}; +typedef struct basic_restr +{ + uint32_t prop_type; + t_optype op; + t_value_holder *values; +} t_basic_restr; + +typedef struct basic_query +{ + struct GUID guid; + const struct full_propset_info *prop_info; + char *prop; + t_basic_restr *basic_restriction; +} t_basic_query; + +t_basic_query *create_basic_query(TALLOC_CTX *ctx, const char *prop, t_basic_restr *restr); + +typedef struct restr +{ + t_nodetype type; + struct restr *left; + struct restr *right; + t_basic_restr *basic_restr; +} t_restr; + +t_restr *create_restr(TALLOC_CTX *ctx, t_nodetype op, t_restr *left, t_restr *right, t_basic_restr *value); + +t_basic_restr *create_basic_restr(TALLOC_CTX *ctx, + uint32_t prop_type, + t_optype op, + t_value_holder *values); + +typedef struct query +{ + t_nodetype type; + struct query *left; + struct query *right; + struct wsp_crestriction *restriction; +} t_query; + +t_query *create_query_node(TALLOC_CTX *ctx, t_nodetype op, t_query *left, t_query *right, t_basic_query *value); + + +typedef struct col_list { + int num_cols; + char **cols; +} t_col_list; + +typedef struct select_stmt { + t_col_list *cols; + t_query *where; +} t_select_stmt; + +t_col_list *create_cols(TALLOC_CTX *ctx, const char *col, t_col_list *append_list); +t_select_stmt *create_select(TALLOC_CTX *ctx, t_col_list *cols, t_query *where); + +t_select_stmt *get_wsp_sql_tree(const char *expr); +t_value_holder *create_string_val(TALLOC_CTX*, const char *text); +t_value_holder *create_num_val(TALLOC_CTX*, int64_t val); +t_value_holder *create_bool_val(TALLOC_CTX*, bool val); +t_value_holder *create_value_range(TALLOC_CTX*, + t_value_holder *left, + t_value_holder *right); +t_value_holder *create_date_range_shortcut(TALLOC_CTX *ctx, + daterange_type daterange); +t_value_holder *create_size_range_shortcut(TALLOC_CTX *ctx, + sizerange_type size); +#endif // __EXPRESSION_H__ diff --git a/source4/libcli/wsp/wsp_aqs_lexer.c b/source4/libcli/wsp/wsp_aqs_lexer.c new file mode 100644 index 0000000..79b5f93 --- /dev/null +++ b/source4/libcli/wsp/wsp_aqs_lexer.c @@ -0,0 +1,2305 @@ +#line 2 "wsp_aqs_lexer.c" + +#line 4 "wsp_aqs_lexer.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 37 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yyg->yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yyg->yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ,yyscanner ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = yyg->yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ + ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] + +void yyrestart (FILE *input_file ,yyscan_t yyscanner ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void yypop_buffer_state (yyscan_t yyscanner ); + +static void yyensure_buffer_stack (yyscan_t yyscanner ); +static void yy_load_buffer_state (yyscan_t yyscanner ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); + +void *yyalloc (yy_size_t ,yyscan_t yyscanner ); +void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); +void yyfree (void * ,yyscan_t yyscanner ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap(yyscanner) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +typedef int yy_state_type; + +#define yytext_ptr yytext_r + +static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); +static int yy_get_next_buffer (yyscan_t yyscanner ); +static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yyg->yytext_ptr = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + yyg->yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yyg->yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 49 +#define YY_END_OF_BUFFER 50 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[153] = + { 0, + 1, 1, 50, 48, 1, 1, 48, 47, 48, 12, + 13, 14, 30, 47, 2, 19, 10, 48, 11, 47, + 24, 22, 47, 23, 47, 47, 47, 25, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 1, 7, + 0, 46, 47, 0, 20, 21, 47, 2, 9, 6, + 8, 47, 28, 26, 47, 27, 47, 4, 47, 29, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 46, 3, 5, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 44, 47, 47, 47, + + 47, 47, 40, 47, 17, 47, 47, 15, 39, 18, + 47, 43, 47, 47, 47, 47, 41, 47, 47, 47, + 31, 47, 16, 47, 47, 47, 47, 42, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 45, 47, 34, 38, 47, 33, 37, 47, 36, 35, + 32, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 1, 6, 1, 1, 1, 7, + 8, 1, 1, 9, 10, 11, 1, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 13, 1, 14, + 15, 16, 1, 1, 17, 18, 19, 20, 21, 11, + 22, 23, 11, 11, 24, 25, 26, 27, 28, 11, + 11, 29, 30, 31, 11, 11, 32, 11, 11, 11, + 1, 33, 1, 1, 11, 1, 34, 11, 35, 36, + + 37, 38, 39, 40, 41, 11, 42, 43, 44, 45, + 46, 47, 11, 48, 49, 50, 51, 11, 52, 11, + 53, 11, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[54] = + { 0, + 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, + 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2 + } ; + +static yyconst flex_int16_t yy_base[156] = + { 0, + 0, 0, 205, 206, 52, 54, 189, 57, 54, 206, + 206, 206, 206, 0, 191, 206, 187, 186, 185, 172, + 180, 179, 191, 177, 166, 164, 171, 173, 167, 145, + 154, 146, 135, 151, 147, 139, 34, 145, 74, 206, + 73, 0, 106, 178, 206, 206, 0, 168, 206, 206, + 206, 159, 0, 0, 0, 0, 147, 0, 152, 0, + 155, 128, 131, 134, 133, 35, 135, 136, 128, 123, + 131, 115, 116, 206, 0, 0, 143, 134, 112, 112, + 126, 122, 119, 107, 115, 112, 105, 100, 118, 114, + 100, 130, 127, 94, 109, 100, 0, 107, 35, 87, + + 94, 41, 0, 83, 0, 98, 103, 0, 0, 0, + 83, 0, 86, 94, 93, 85, 0, 82, 90, 89, + 0, 77, 0, 83, 78, 81, 83, 0, 60, 67, + 69, 66, 66, 50, 57, 50, 47, 54, 47, 58, + 0, 51, 0, 0, 49, 0, 0, 33, 0, 0, + 0, 206, 139, 79, 141 + } ; + +static yyconst flex_int16_t yy_def[156] = + { 0, + 152, 1, 152, 152, 152, 152, 152, 153, 152, 152, + 152, 152, 152, 154, 152, 152, 152, 152, 152, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 152, 152, + 155, 154, 153, 155, 152, 152, 154, 152, 152, 152, + 152, 154, 154, 154, 43, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 152, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 0, 152, 152, 152 + } ; + +static yyconst flex_int16_t yy_nxt[260] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 14, 14, 14, + 14, 21, 14, 22, 23, 24, 25, 26, 14, 27, + 28, 29, 4, 14, 14, 14, 30, 31, 32, 33, + 14, 14, 34, 35, 14, 14, 14, 14, 36, 37, + 14, 14, 38, 39, 39, 39, 39, 41, 41, 41, + 41, 42, 41, 41, 41, 41, 41, 45, 46, 41, + 41, 41, 41, 69, 70, 39, 39, 74, 113, 71, + 47, 72, 83, 84, 118, 151, 114, 115, 150, 44, + 149, 148, 119, 120, 147, 146, 145, 144, 143, 142, + + 141, 140, 139, 138, 137, 44, 41, 41, 41, 41, + 42, 41, 41, 41, 41, 41, 136, 135, 41, 41, + 41, 41, 134, 133, 132, 131, 130, 129, 128, 127, + 126, 125, 124, 123, 122, 121, 117, 116, 44, 43, + 43, 41, 41, 112, 111, 110, 109, 108, 107, 106, + 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, + 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, + 85, 82, 81, 80, 79, 78, 77, 76, 75, 48, + 152, 73, 68, 67, 66, 65, 64, 63, 62, 61, + 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, + + 50, 49, 48, 40, 152, 3, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152 + } ; + +static yyconst flex_int16_t yy_chk[260] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 5, 5, 6, 6, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 9, 9, 8, + 8, 8, 8, 37, 37, 39, 39, 41, 99, 37, + 154, 37, 66, 66, 102, 148, 99, 99, 145, 8, + 142, 140, 102, 102, 139, 138, 137, 136, 135, 134, + + 133, 132, 131, 130, 129, 41, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 127, 126, 43, 43, + 43, 43, 125, 124, 122, 120, 119, 118, 116, 115, + 114, 113, 111, 107, 106, 104, 101, 100, 43, 153, + 153, 155, 155, 98, 96, 95, 94, 93, 92, 91, + 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, + 80, 79, 78, 77, 73, 72, 71, 70, 69, 68, + 67, 65, 64, 63, 62, 61, 59, 57, 52, 48, + 44, 38, 36, 35, 34, 33, 32, 31, 30, 29, + 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, + + 18, 17, 15, 7, 3, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152 + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#line 1 "wsp_aqs_lexer.l" +/* + * Unix SMB/CIFS implementation. + * + * Window Search Service + * + * Copyright (c) 2016 Noel Power + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#line 23 "wsp_aqs_lexer.l" + +#include "includes.h" +#include "libcli/wsp/wsp_aqs.h" +#include "libcli/wsp/wsp_aqs_parser.h" + +#include + +#define YY_NO_UNISTD_H 1 +#line 569 "wsp_aqs_lexer.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Holds the entire state of the reentrant scanner. */ +struct yyguts_t + { + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + yy_size_t yy_n_chars; + yy_size_t yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + + char *yytext_r; + int yy_more_flag; + int yy_more_len; + + YYSTYPE * yylval_r; + + }; /* end struct yyguts_t */ + +static int yy_init_globals (yyscan_t yyscanner ); + + /* This must go here because YYSTYPE and YYLTYPE are included + * from bison output in section 1.*/ + # define yylval yyg->yylval_r + +int yylex_init (yyscan_t* scanner); + +int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (yyscan_t yyscanner ); + +int yyget_debug (yyscan_t yyscanner ); + +void yyset_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *yyget_in (yyscan_t yyscanner ); + +void yyset_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *yyget_out (yyscan_t yyscanner ); + +void yyset_out (FILE * out_str ,yyscan_t yyscanner ); + +yy_size_t yyget_leng (yyscan_t yyscanner ); + +char *yyget_text (yyscan_t yyscanner ); + +int yyget_lineno (yyscan_t yyscanner ); + +void yyset_lineno (int line_number ,yyscan_t yyscanner ); + +int yyget_column (yyscan_t yyscanner ); + +void yyset_column (int column_no ,yyscan_t yyscanner ); + +YYSTYPE * yyget_lval (yyscan_t yyscanner ); + +void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (yyscan_t yyscanner ); +#else +extern int yywrap (yyscan_t yyscanner ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (yyscan_t yyscanner ); +#else +static int input (yyscan_t yyscanner ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex \ + (YYSTYPE * yylval_param ,yyscan_t yyscanner); + +#define YY_DECL int yylex \ + (YYSTYPE * yylval_param , yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + +#line 91 "wsp_aqs_lexer.l" + + +#line 809 "wsp_aqs_lexer.c" + + yylval = yylval_param; + + if ( !yyg->yy_init ) + { + yyg->yy_init = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yyg->yy_start ) + yyg->yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + yy_load_buffer_state(yyscanner ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yyg->yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yyg->yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yyg->yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 153 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_current_state != 152 ); + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yyg->yy_hold_char; + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + +case 1: +/* rule 1 can match eol */ +YY_RULE_SETUP +#line 93 "wsp_aqs_lexer.l" +{ /* Skip blanks. */ } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 95 "wsp_aqs_lexer.l" +{ sscanf(yytext, "%"PRId64, &yylval->num); return TOKEN_NUMBER; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 97 "wsp_aqs_lexer.l" +{ return TOKEN_AND; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 98 "wsp_aqs_lexer.l" +{ return TOKEN_OR; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 99 "wsp_aqs_lexer.l" +{ return TOKEN_NOT; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 100 "wsp_aqs_lexer.l" +{ return TOKEN_EQ; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 101 "wsp_aqs_lexer.l" +{ return TOKEN_NE; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 102 "wsp_aqs_lexer.l" +{ return TOKEN_GE; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 103 "wsp_aqs_lexer.l" +{ return TOKEN_LE; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 104 "wsp_aqs_lexer.l" +{ return TOKEN_LT; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 105 "wsp_aqs_lexer.l" +{ return TOKEN_GT; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 106 "wsp_aqs_lexer.l" +{ return TOKEN_LPAREN; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 107 "wsp_aqs_lexer.l" +{ return TOKEN_RPAREN; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 108 "wsp_aqs_lexer.l" +{ return TOKEN_COMMA; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 109 "wsp_aqs_lexer.l" +{ return TOKEN_WHERE; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 110 "wsp_aqs_lexer.l" +{ return TOKEN_SELECT; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 111 "wsp_aqs_lexer.l" +{ return TOKEN_TRUE; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 112 "wsp_aqs_lexer.l" +{ return TOKEN_FALSE; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 113 "wsp_aqs_lexer.l" +{ return TOKEN_PROP_EQUALS; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 115 "wsp_aqs_lexer.l" +{ return TOKEN_STARTS_WITH;} + YY_BREAK +case 21: +YY_RULE_SETUP +#line 116 "wsp_aqs_lexer.l" +{ return TOKEN_EQUALS;} + YY_BREAK +case 22: +YY_RULE_SETUP +#line 118 "wsp_aqs_lexer.l" +{ return TOKEN_K; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 119 "wsp_aqs_lexer.l" +{ return TOKEN_M; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 120 "wsp_aqs_lexer.l" +{ return TOKEN_G; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 121 "wsp_aqs_lexer.l" +{ return TOKEN_T; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 122 "wsp_aqs_lexer.l" +{ return TOKEN_KB; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 123 "wsp_aqs_lexer.l" +{ return TOKEN_MB; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 124 "wsp_aqs_lexer.l" +{ return TOKEN_GB; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 125 "wsp_aqs_lexer.l" +{ return TOKEN_TB; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 126 "wsp_aqs_lexer.l" +{ return TOKEN_RANGE; } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 127 "wsp_aqs_lexer.l" +{ return TOKEN_TODAY; } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 128 "wsp_aqs_lexer.l" +{ return TOKEN_YESTERDAY;} + YY_BREAK +case 33: +YY_RULE_SETUP +#line 129 "wsp_aqs_lexer.l" +{ return TOKEN_THISWEEK;} + YY_BREAK +case 34: +YY_RULE_SETUP +#line 130 "wsp_aqs_lexer.l" +{ return TOKEN_LASTWEEK;} + YY_BREAK +case 35: +YY_RULE_SETUP +#line 131 "wsp_aqs_lexer.l" +{ return TOKEN_THISMONTH; } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 132 "wsp_aqs_lexer.l" +{ return TOKEN_LASTMONTH; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 133 "wsp_aqs_lexer.l" +{ return TOKEN_THISYEAR; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 134 "wsp_aqs_lexer.l" +{ return TOKEN_LASTYEAR; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 135 "wsp_aqs_lexer.l" +{ return TOKEN_EMPTY; } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 136 "wsp_aqs_lexer.l" +{ return TOKEN_TINY; } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 137 "wsp_aqs_lexer.l" +{ return TOKEN_SMALL; } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 138 "wsp_aqs_lexer.l" +{ return TOKEN_MEDIUM; } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 139 "wsp_aqs_lexer.l" +{ return TOKEN_LARGE; } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 140 "wsp_aqs_lexer.l" +{ return TOKEN_HUGE; } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 141 "wsp_aqs_lexer.l" +{ return TOKEN_GIGANTIC; } + YY_BREAK +case 46: +/* rule 46 can match eol */ +YY_RULE_SETUP +#line 144 "wsp_aqs_lexer.l" +{ yylval->strval = talloc_asprintf(talloc_tos(), "%s", yytext); return TOKEN_STRING_LITERAL; } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 146 "wsp_aqs_lexer.l" +{ yylval->strval = talloc_asprintf(talloc_tos(), "%s", yytext); return TOKEN_IDENTIFIER; } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 147 "wsp_aqs_lexer.l" +{ } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 149 "wsp_aqs_lexer.l" +YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK +#line 1137 "wsp_aqs_lexer.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yyg->yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); + + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yyg->yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_END_OF_FILE: + { + yyg->yy_did_buffer_switch_on_eof = 0; + + if ( yywrap(yyscanner ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = + yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yyg->yy_c_buf_p = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = yyg->yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) (yyg->yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + yyg->yy_n_chars, num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + if ( yyg->yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ,yyscanner); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + yyg->yy_n_chars += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_current_state = yyg->yy_start; + + for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 153 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) +{ + register int yy_is_jam; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ + register char *yy_cp = yyg->yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 153 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 152); + + (void)yyg; + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) +{ + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_cp = yyg->yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yyg->yy_hold_char; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register yy_size_t number_to_move = yyg->yy_n_chars + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + yyg->yytext_ptr = yy_bp; + yyg->yy_hold_char = *yy_cp; + yyg->yy_c_buf_p = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (yyscan_t yyscanner) +#else + static int input (yyscan_t yyscanner) +#endif + +{ + int c; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + *yyg->yy_c_buf_p = yyg->yy_hold_char; + + if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + /* This was really a NUL. */ + *yyg->yy_c_buf_p = '\0'; + + else + { /* need more input */ + yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + ++yyg->yy_c_buf_p; + + switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ,yyscanner); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap(yyscanner ) ) + return EOF; + + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(yyscanner); +#else + return input(yyscanner); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = yyg->yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ + *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ + yyg->yy_hold_char = *++yyg->yy_c_buf_p; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * @param yyscanner The scanner object. + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); + yy_load_buffer_state(yyscanner ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * @param yyscanner The scanner object. + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (yyscanner); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state(yyscanner ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yyg->yy_did_buffer_switch_on_eof = 1; +} + +static void yy_load_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + yyg->yy_hold_char = *yyg->yy_c_buf_p; +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * @param yyscanner The scanner object. + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ,yyscanner); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * @param yyscanner The scanner object. + */ + void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ,yyscanner ); + + yyfree((void *) b ,yyscanner ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) + +{ + int oerrno = errno; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_flush_buffer(b ,yyscanner); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * @param yyscanner The scanner object. + */ + void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state(yyscanner ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * @param yyscanner The scanner object. + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(yyscanner); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + yyg->yy_buffer_stack_top++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * @param yyscanner The scanner object. + */ +void yypop_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); + YY_CURRENT_BUFFER_LVALUE = NULL; + if (yyg->yy_buffer_stack_top > 0) + --yyg->yy_buffer_stack_top; + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (yyscan_t yyscanner) +{ + yy_size_t num_to_alloc; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (!yyg->yy_buffer_stack) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + yyg->yy_buffer_stack_max = num_to_alloc; + yyg->yy_buffer_stack_top = 0; + return; + } + + if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = yyg->yy_buffer_stack_max + grow_size; + yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc + (yyg->yy_buffer_stack, + num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); + yyg->yy_buffer_stack_max = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ,yyscanner ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ,yyscanner ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ,yyscanner); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = yyg->yy_hold_char; \ + yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ + yyg->yy_hold_char = *yyg->yy_c_buf_p; \ + *yyg->yy_c_buf_p = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the user-defined data for this scanner. + * @param yyscanner The scanner object. + */ +YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyextra; +} + +/** Get the current line number. + * @param yyscanner The scanner object. + */ +int yyget_lineno (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yylineno; +} + +/** Get the current column number. + * @param yyscanner The scanner object. + */ +int yyget_column (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yycolumn; +} + +/** Get the input stream. + * @param yyscanner The scanner object. + */ +FILE *yyget_in (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyin; +} + +/** Get the output stream. + * @param yyscanner The scanner object. + */ +FILE *yyget_out (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyout; +} + +/** Get the length of the current token. + * @param yyscanner The scanner object. + */ +yy_size_t yyget_leng (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyleng; +} + +/** Get the current token. + * @param yyscanner The scanner object. + */ + +char *yyget_text (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yytext; +} + +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * @param yyscanner The scanner object. + */ +void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyextra = user_defined ; +} + +/** Set the current line number. + * @param line_number + * @param yyscanner The scanner object. + */ +void yyset_lineno (int line_number , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); + + yylineno = line_number; +} + +/** Set the current column. + * @param line_number + * @param yyscanner The scanner object. + */ +void yyset_column (int column_no , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + YY_FATAL_ERROR( "yyset_column called with no buffer" ); + + yycolumn = column_no; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * @param yyscanner The scanner object. + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyin = in_str ; +} + +void yyset_out (FILE * out_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyout = out_str ; +} + +int yyget_debug (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yy_flex_debug; +} + +void yyset_debug (int bdebug , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yy_flex_debug = bdebug ; +} + +/* Accessor methods for yylval and yylloc */ + +YYSTYPE * yyget_lval (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylval; +} + +void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylval = yylval_param; +} + +/* User-visible API */ + +/* yylex_init is special because it creates the scanner itself, so it is + * the ONLY reentrant function that doesn't take the scanner as the last argument. + * That's why we explicitly handle the declaration, instead of using our macros. + */ + +int yylex_init(yyscan_t* ptr_yy_globals) + +{ + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + return yy_init_globals ( *ptr_yy_globals ); +} + +/* yylex_init_extra has the same functionality as yylex_init, but follows the + * convention of taking the scanner as the last argument. Note however, that + * this is a *pointer* to a scanner, as it will be allocated by this call (and + * is the reason, too, why this function also must handle its own declaration). + * The user defined value in the first argument will be available to yyalloc in + * the yyextra field. + */ + +int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) + +{ + struct yyguts_t dummy_yyguts; + + yyset_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in + yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + yyset_extra (yy_user_defined, *ptr_yy_globals); + + return yy_init_globals ( *ptr_yy_globals ); +} + +static int yy_init_globals (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + yyg->yy_buffer_stack = 0; + yyg->yy_buffer_stack_top = 0; + yyg->yy_buffer_stack_max = 0; + yyg->yy_c_buf_p = (char *) 0; + yyg->yy_init = 0; + yyg->yy_start = 0; + + yyg->yy_start_stack_ptr = 0; + yyg->yy_start_stack_depth = 0; + yyg->yy_start_stack = NULL; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(yyscanner); + } + + /* Destroy the stack itself. */ + yyfree(yyg->yy_buffer_stack ,yyscanner); + yyg->yy_buffer_stack = NULL; + + /* Destroy the start condition stack. */ + yyfree(yyg->yy_start_stack ,yyscanner ); + yyg->yy_start_stack = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( yyscanner); + + /* Destroy the main struct (reentrant only). */ + yyfree ( yyscanner , yyscanner ); + yyscanner = NULL; + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size , yyscan_t yyscanner) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr , yyscan_t yyscanner) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 149 "wsp_aqs_lexer.l" + + + + diff --git a/source4/libcli/wsp/wsp_aqs_lexer.h b/source4/libcli/wsp/wsp_aqs_lexer.h new file mode 100644 index 0000000..b55f088 --- /dev/null +++ b/source4/libcli/wsp/wsp_aqs_lexer.h @@ -0,0 +1,346 @@ +#ifndef yyHEADER_H +#define yyHEADER_H 1 +#define yyIN_HEADER 1 + +#line 6 "wsp_aqs_lexer.h" + +#line 8 "wsp_aqs_lexer.h" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 37 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +void yyrestart (FILE *input_file ,yyscan_t yyscanner ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void yypop_buffer_state (yyscan_t yyscanner ); + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); + +void *yyalloc (yy_size_t ,yyscan_t yyscanner ); +void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); +void yyfree (void * ,yyscan_t yyscanner ); + +/* Begin user sect3 */ + +#define yywrap(yyscanner) 1 +#define YY_SKIP_YYWRAP + +#define yytext_ptr yytext_r + +#ifdef YY_HEADER_EXPORT_START_CONDITIONS +#define INITIAL 0 + +#endif + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +int yylex_init (yyscan_t* scanner); + +int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (yyscan_t yyscanner ); + +int yyget_debug (yyscan_t yyscanner ); + +void yyset_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *yyget_in (yyscan_t yyscanner ); + +void yyset_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *yyget_out (yyscan_t yyscanner ); + +void yyset_out (FILE * out_str ,yyscan_t yyscanner ); + +yy_size_t yyget_leng (yyscan_t yyscanner ); + +char *yyget_text (yyscan_t yyscanner ); + +int yyget_lineno (yyscan_t yyscanner ); + +void yyset_lineno (int line_number ,yyscan_t yyscanner ); + +int yyget_column (yyscan_t yyscanner ); + +void yyset_column (int column_no ,yyscan_t yyscanner ); + +YYSTYPE * yyget_lval (yyscan_t yyscanner ); + +void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (yyscan_t yyscanner ); +#else +extern int yywrap (yyscan_t yyscanner ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex \ + (YYSTYPE * yylval_param ,yyscan_t yyscanner); + +#define YY_DECL int yylex \ + (YYSTYPE * yylval_param , yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +#line 149 "wsp_aqs_lexer.l" + + +#line 345 "wsp_aqs_lexer.h" +#undef yyIN_HEADER +#endif /* yyHEADER_H */ diff --git a/source4/libcli/wsp/wsp_aqs_lexer.l b/source4/libcli/wsp/wsp_aqs_lexer.l new file mode 100644 index 0000000..14fda37 --- /dev/null +++ b/source4/libcli/wsp/wsp_aqs_lexer.l @@ -0,0 +1,150 @@ +/* + * Unix SMB/CIFS implementation. + * + * Window Search Service + * + * Copyright (c) 2016 Noel Power + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +%{ + +#include "includes.h" +#include "libcli/wsp/wsp_aqs.h" +#include "libcli/wsp/wsp_aqs_parser.h" + +#include + +%} + +%option outfile="wsp_aqs_lexer.c" header-file="wsp_aqs_lexer.h" +%option warn nodefault + +%option reentrant noyywrap never-interactive nounistd +%option bison-bridge + +LPAREN "(" +RPAREN ")" +AND "AND" +OR "OR" +NOT "NOT" +EQ "==" +NE "!=" +GE ">=" +LE "<=" +LESS "<" +GREATER ">" +COMMA "," +WHERE "WHERE" +SELECT "SELECT" +PROP_EQUALS ":" +TRUE "true" +FALSE "false" + +TODAY "today" +YESTERDAY "yesterday" +THISWEEK "thisweek" +LASTWEEK "lastweek" +THISMONTH "thismonth" +LASTMONTH "lastmonth" +THISYEAR "thisyear" +LASTYEAR "lastyear" + +EMPTY "empty" +TINY "tiny" +SMALL "small" +MEDIUM "medium" +LARGE "large" +HUGE "huge" +GIGANTIC "gigantic" + +STARTS_WITH "$<" +EQUALS "$=" +K "K" +M "M" +G "G" +T "T" +KB "KB" +MB "MB" +GB "GB" +TB "TB" +RANGE "-" + + +NUMBER [0-9]+ +WS [ \r\n\t]* +IDENTIFIER [a-z\."A-Z_][a-z\."A-Z_0-9]* +STRING_LITERAL L?\"(\\.|[^\\"])*\" + +%% + +{WS} { /* Skip blanks. */ } + +{NUMBER} { sscanf(yytext, "%"PRId64, &yylval->num); return TOKEN_NUMBER; } + +{AND} { return TOKEN_AND; } +{OR} { return TOKEN_OR; } +{NOT} { return TOKEN_NOT; } +{EQ} { return TOKEN_EQ; } +{NE} { return TOKEN_NE; } +{GE} { return TOKEN_GE; } +{LE} { return TOKEN_LE; } +{LESS} { return TOKEN_LT; } +{GREATER} { return TOKEN_GT; } +{LPAREN} { return TOKEN_LPAREN; } +{RPAREN} { return TOKEN_RPAREN; } +{COMMA} { return TOKEN_COMMA; } +{WHERE} { return TOKEN_WHERE; } +{SELECT} { return TOKEN_SELECT; } +{TRUE} { return TOKEN_TRUE; } +{FALSE} { return TOKEN_FALSE; } +{PROP_EQUALS} { return TOKEN_PROP_EQUALS; } + +{STARTS_WITH} { return TOKEN_STARTS_WITH;} +{EQUALS} { return TOKEN_EQUALS;} + +{K} { return TOKEN_K; } +{M} { return TOKEN_M; } +{G} { return TOKEN_G; } +{T} { return TOKEN_T; } +{KB} { return TOKEN_KB; } +{MB} { return TOKEN_MB; } +{GB} { return TOKEN_GB; } +{TB} { return TOKEN_TB; } +{RANGE} { return TOKEN_RANGE; } +{TODAY} { return TOKEN_TODAY; } +{YESTERDAY} { return TOKEN_YESTERDAY;} +{THISWEEK} { return TOKEN_THISWEEK;} +{LASTWEEK} { return TOKEN_LASTWEEK;} +{THISMONTH} { return TOKEN_THISMONTH; } +{LASTMONTH} { return TOKEN_LASTMONTH; } +{THISYEAR} { return TOKEN_THISYEAR; } +{LASTYEAR} { return TOKEN_LASTYEAR; } +{EMPTY} { return TOKEN_EMPTY; } +{TINY} { return TOKEN_TINY; } +{SMALL} { return TOKEN_SMALL; } +{MEDIUM} { return TOKEN_MEDIUM; } +{LARGE} { return TOKEN_LARGE; } +{HUGE} { return TOKEN_HUGE; } +{GIGANTIC} { return TOKEN_GIGANTIC; } + + +{STRING_LITERAL} { yylval->strval = talloc_asprintf(talloc_tos(), "%s", yytext); return TOKEN_STRING_LITERAL; } + +{IDENTIFIER} { yylval->strval = talloc_asprintf(talloc_tos(), "%s", yytext); return TOKEN_IDENTIFIER; } +. { } + +%% + diff --git a/source4/libcli/wsp/wsp_aqs_parser.c b/source4/libcli/wsp/wsp_aqs_parser.c new file mode 100644 index 0000000..c7ceecd --- /dev/null +++ b/source4/libcli/wsp/wsp_aqs_parser.c @@ -0,0 +1,2319 @@ +/* A Bison parser, made by GNU Bison 2.7. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.7" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* Copy the first part of user declarations. */ +/* Line 371 of yacc.c */ +#line 22 "wsp_aqs_parser.y" + + +#include "includes.h" +#include "libcli/wsp/wsp_aqs.h" +#include "libcli/wsp/wsp_aqs_parser.h" +#include "libcli/wsp/wsp_aqs_lexer.h" + +static int yyerror(t_select_stmt **stmt, yyscan_t scanner, const char *msg) +{ + fprintf(stderr,"Error :%s\n",msg); return 0; +} + +/* Line 371 of yacc.c */ +#line 81 "wsp_aqs_parser.c" + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "wsp_aqs_parser.h". */ +#ifndef YY_YY_WSP_AQS_PARSER_H_INCLUDED +# define YY_YY_WSP_AQS_PARSER_H_INCLUDED +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif +/* "%code requires" blocks. */ +/* Line 387 of yacc.c */ +#line 34 "wsp_aqs_parser.y" + + +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + + + +/* Line 387 of yacc.c */ +#line 123 "wsp_aqs_parser.c" + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + TOKEN_AND = 259, + TOKEN_OR = 261, + TOKEN_NE = 263, + TOKEN_GE = 265, + TOKEN_LE = 267, + TOKEN_LT = 269, + TOKEN_GT = 271, + TOKEN_NOT = 273, + TOKEN_EQ = 275, + TOKEN_PROP_EQUALS = 277, + TOKEN_STARTS_WITH = 279, + TOKEN_EQUALS = 281, + TOKEN_LPAREN = 282, + TOKEN_RPAREN = 283, + TOKEN_WHERE = 284, + TOKEN_SELECT = 285, + TOKEN_TRUE = 286, + TOKEN_FALSE = 287, + TOKEN_COMMA = 288, + TOKEN_MATCHES = 289, + TOKEN_K = 290, + TOKEN_M = 291, + TOKEN_G = 292, + TOKEN_T = 293, + TOKEN_KB = 294, + TOKEN_MB = 295, + TOKEN_GB = 296, + TOKEN_TB = 297, + TOKEN_RANGE = 298, + TOKEN_TODAY = 299, + TOKEN_YESTERDAY = 300, + TOKEN_THISWEEK = 301, + TOKEN_LASTWEEK = 302, + TOKEN_THISMONTH = 303, + TOKEN_LASTMONTH = 304, + TOKEN_THISYEAR = 305, + TOKEN_LASTYEAR = 306, + TOKEN_EMPTY = 307, + TOKEN_TINY = 308, + TOKEN_SMALL = 309, + TOKEN_MEDIUM = 310, + TOKEN_LARGE = 311, + TOKEN_HUGE = 312, + TOKEN_GIGANTIC = 313, + TOKEN_NUMBER = 314, + TOKEN_IDENTIFIER = 315, + TOKEN_STRING_LITERAL = 316 + }; +#endif + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 387 of yacc.c */ +#line 51 "wsp_aqs_parser.y" + + char *strval; + int64_t num; + t_value_holder *value; + t_select_stmt *select_stmt; + t_select_stmt *query_stmt; + t_basic_restr *bas_rest; + t_basic_query *bas_query; + t_restr *restr; + t_query *query; + t_col_list *columns; + daterange_type daterange; + sizerange_type sizerange; + t_optype prop_op; + + +/* Line 387 of yacc.c */ +#line 204 "wsp_aqs_parser.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (t_select_stmt **select, yyscan_t scanner); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !YY_YY_WSP_AQS_PARSER_H_INCLUDED */ + +/* Copy the second part of user declarations. */ + +/* Line 390 of yacc.c */ +#line 231 "wsp_aqs_parser.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(N) (N) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 15 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 107 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 62 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 16 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 61 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 81 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 316 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 5, 10, 12, 14, 18, 20, 22, + 26, 30, 34, 37, 41, 43, 45, 48, 51, 55, + 57, 59, 61, 63, 65, 67, 69, 71, 73, 77, + 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, + 99, 101, 103, 105, 107, 109, 111, 113, 116, 119, + 122, 125, 128, 131, 134, 137, 139, 141, 143, 145, + 147, 151 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 63, 0, -1, 64, -1, 30, 65, 29, 67, -1, + 67, -1, 66, -1, 66, 33, 65, -1, 60, -1, + 68, -1, 27, 67, 28, -1, 67, 4, 67, -1, + 67, 6, 67, -1, 18, 67, -1, 69, 22, 70, + -1, 60, -1, 73, -1, 71, 73, -1, 72, 73, + -1, 27, 77, 28, -1, 20, -1, 8, -1, 10, + -1, 12, -1, 14, -1, 16, -1, 24, -1, 26, + -1, 76, -1, 76, 43, 76, -1, 74, -1, 75, + -1, 44, -1, 45, -1, 46, -1, 47, -1, 48, + -1, 49, -1, 50, -1, 51, -1, 52, -1, 53, + -1, 54, -1, 55, -1, 56, -1, 57, -1, 58, + -1, 59, -1, 59, 35, -1, 59, 36, -1, 59, + 37, -1, 59, 38, -1, 59, 39, -1, 59, 40, + -1, 59, 41, -1, 59, 42, -1, 31, -1, 32, + -1, 61, -1, 60, -1, 70, -1, 77, 4, 77, + -1, 77, 6, 77, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 140, 140, 146, 152, 161, 167, 176, 185, 191, + 197, 203, 209, 218, 226, 235, 241, 247, 253, 265, + 266, 267, 268, 269, 270, 274, 275, 279, 280, 286, + 292, 301, 302, 303, 304, 305, 306, 307, 308, 312, + 313, 314, 315, 316, 317, 318, 322, 328, 334, 340, + 346, 353, 359, 365, 371, 378, 384, 390, 398, 406, + 412, 418 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "\"AND\"", "TOKEN_AND", "\"OR\"", + "TOKEN_OR", "\"!=\"", "TOKEN_NE", "\">=\"", "TOKEN_GE", "\"<=\"", + "TOKEN_LE", "\"<\"", "TOKEN_LT", "\">\"", "TOKEN_GT", "\"NOT\"", + "TOKEN_NOT", "\"==\"", "TOKEN_EQ", "\":\"", "TOKEN_PROP_EQUALS", + "\"$<\"", "TOKEN_STARTS_WITH", "\"$=\"", "TOKEN_EQUALS", "TOKEN_LPAREN", + "TOKEN_RPAREN", "TOKEN_WHERE", "TOKEN_SELECT", "TOKEN_TRUE", + "TOKEN_FALSE", "TOKEN_COMMA", "TOKEN_MATCHES", "TOKEN_K", "TOKEN_M", + "TOKEN_G", "TOKEN_T", "TOKEN_KB", "TOKEN_MB", "TOKEN_GB", "TOKEN_TB", + "TOKEN_RANGE", "TOKEN_TODAY", "TOKEN_YESTERDAY", "TOKEN_THISWEEK", + "TOKEN_LASTWEEK", "TOKEN_THISMONTH", "TOKEN_LASTMONTH", "TOKEN_THISYEAR", + "TOKEN_LASTYEAR", "TOKEN_EMPTY", "TOKEN_TINY", "TOKEN_SMALL", + "TOKEN_MEDIUM", "TOKEN_LARGE", "TOKEN_HUGE", "TOKEN_GIGANTIC", + "TOKEN_NUMBER", "TOKEN_IDENTIFIER", "TOKEN_STRING_LITERAL", "$accept", + "input", "select_stmt", "cols", "col", "query", "basic_query", "prop", + "basic_restr", "property_op", "content_op", "value", "date_shortcut", + "size_shortcut", "simple_value", "restr", YY_NULL +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 62, 63, 64, 64, 65, 65, 66, 67, 67, + 67, 67, 67, 68, 69, 70, 70, 70, 70, 71, + 71, 71, 71, 71, 71, 72, 72, 73, 73, 73, + 73, 74, 74, 74, 74, 74, 74, 74, 74, 75, + 75, 75, 75, 75, 75, 75, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, + 77, 77 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 4, 1, 1, 3, 1, 1, 3, + 3, 3, 2, 3, 1, 1, 2, 2, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, + 3, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 0, 0, 0, 14, 0, 2, 4, 8, 0, + 12, 0, 7, 0, 5, 1, 0, 0, 0, 9, + 0, 0, 10, 11, 20, 21, 22, 23, 24, 19, + 25, 26, 0, 55, 56, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 58, 57, 13, 0, 0, 15, 29, 30, 27, + 3, 6, 59, 0, 47, 48, 49, 50, 51, 52, + 53, 54, 16, 17, 0, 0, 0, 18, 28, 60, + 61 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 5, 6, 13, 14, 7, 8, 9, 62, 54, + 55, 56, 57, 58, 59, 63 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -62 +static const yytype_int8 yypact[] = +{ + -5, -1, -1, -55, -62, 20, -62, -3, -62, 5, + -62, 3, -62, 0, -12, -62, -1, -1, -8, -62, + -1, -55, 22, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -8, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + 55, -62, -62, -62, 25, 25, -62, -62, -62, -13, + -3, -62, -62, 59, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, 1, -8, -8, -62, -62, 28, + -62 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -62, -62, -62, 14, -62, 87, -62, -62, 36, -62, + -62, -44, -62, -62, -16, -61 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 24, 16, 25, 17, 26, 12, 27, 16, 28, 17, + 72, 73, 29, 1, 79, 80, 30, 1, 31, 32, + 15, 21, 2, 33, 34, 3, 2, 18, 17, 20, + 74, 19, 33, 34, 76, 61, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 4, 33, 34, 78, 4, + 50, 51, 52, 75, 0, 76, 0, 0, 0, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 77, 10, 11, + 64, 65, 66, 67, 68, 69, 70, 71, 0, 0, + 0, 0, 0, 22, 23, 0, 0, 60 +}; + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-62))) + +#define yytable_value_is_error(Yytable_value) \ + YYID (0) + +static const yytype_int8 yycheck[] = +{ + 8, 4, 10, 6, 12, 60, 14, 4, 16, 6, + 54, 55, 20, 18, 75, 76, 24, 18, 26, 27, + 0, 33, 27, 31, 32, 30, 27, 22, 6, 29, + 43, 28, 31, 32, 6, 21, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 18, 60, 31, 32, 74, 60, + 59, 60, 61, 4, -1, 6, -1, -1, -1, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 28, 1, 2, + 35, 36, 37, 38, 39, 40, 41, 42, -1, -1, + -1, -1, -1, 16, 17, -1, -1, 20 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 18, 27, 30, 60, 63, 64, 67, 68, 69, + 67, 67, 60, 65, 66, 0, 4, 6, 22, 28, + 29, 33, 67, 67, 8, 10, 12, 14, 16, 20, + 24, 26, 27, 31, 32, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 70, 71, 72, 73, 74, 75, 76, + 67, 65, 70, 77, 35, 36, 37, 38, 39, 40, + 41, 42, 73, 73, 43, 4, 6, 28, 76, 77, + 77 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (select, scanner, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, scanner) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, select, scanner); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, t_select_stmt **select, yyscan_t scanner) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, select, scanner) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + t_select_stmt **select; + yyscan_t scanner; +#endif +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; + YYUSE (select); + YYUSE (scanner); +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, t_select_stmt **select, yyscan_t scanner) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, select, scanner) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + t_select_stmt **select; + yyscan_t scanner; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep, select, scanner); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule, t_select_stmt **select, yyscan_t scanner) +#else +static void +yy_reduce_print (yyvsp, yyrule, select, scanner) + YYSTYPE *yyvsp; + int yyrule; + t_select_stmt **select; + yyscan_t scanner; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , select, scanner); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule, select, scanner); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULL; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, t_select_stmt **select, yyscan_t scanner) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, select, scanner) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + t_select_stmt **select; + yyscan_t scanner; +#endif +{ + YYUSE (yyvaluep); + YYUSE (select); + YYUSE (scanner); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (t_select_stmt **select, yyscan_t scanner) +#else +int +yyparse (select, scanner) + t_select_stmt **select; + yyscan_t scanner; +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + + +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +/* Default value used for initialization, for pacifying older GCCs + or non-GCC compilers. */ +static YYSTYPE yyval_default; +# define YY_INITIAL_VALUE(Value) = Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +/* Line 1792 of yacc.c */ +#line 140 "wsp_aqs_parser.y" + { + *select = (yyvsp[(1) - (1)].select_stmt); + } + break; + + case 3: +/* Line 1792 of yacc.c */ +#line 146 "wsp_aqs_parser.y" + { + (yyval.select_stmt) = create_select(talloc_tos(), (yyvsp[(2) - (4)].columns), (yyvsp[(4) - (4)].query) ); + if (!(yyval.select_stmt)) { + YYERROR; + } + } + break; + + case 4: +/* Line 1792 of yacc.c */ +#line 152 "wsp_aqs_parser.y" + { + (yyval.select_stmt) = create_select(talloc_tos(), NULL, (yyvsp[(1) - (1)].query) ); + if (!(yyval.select_stmt)) { + YYERROR; + } + } + break; + + case 5: +/* Line 1792 of yacc.c */ +#line 161 "wsp_aqs_parser.y" + { + (yyval.columns) = create_cols(talloc_tos(), (yyvsp[(1) - (1)].strval), NULL); + if (!(yyval.columns)) { + YYERROR; + } + } + break; + + case 6: +/* Line 1792 of yacc.c */ +#line 167 "wsp_aqs_parser.y" + { + (yyval.columns) = create_cols(talloc_tos(), (yyvsp[(1) - (3)].strval), (yyvsp[(3) - (3)].columns)); + if (!(yyval.columns)) { + YYERROR; + } + } + break; + + case 7: +/* Line 1792 of yacc.c */ +#line 176 "wsp_aqs_parser.y" + { + (yyval.strval) = (yyvsp[(1) - (1)].strval); + if (!(yyval.strval)) { + YYERROR; + } + } + break; + + case 8: +/* Line 1792 of yacc.c */ +#line 185 "wsp_aqs_parser.y" + { + (yyval.query) = create_query_node(talloc_tos(), eVALUE, NULL, NULL, (yyvsp[(1) - (1)].bas_query)); + if (!(yyval.query)) { + YYERROR; + } + } + break; + + case 9: +/* Line 1792 of yacc.c */ +#line 191 "wsp_aqs_parser.y" + { + (yyval.query) = (yyvsp[(2) - (3)].query); + if (!(yyval.query)) { + YYERROR; + } + } + break; + + case 10: +/* Line 1792 of yacc.c */ +#line 197 "wsp_aqs_parser.y" + { + (yyval.query) = create_query_node(talloc_tos(), eAND, (yyvsp[(1) - (3)].query), (yyvsp[(3) - (3)].query), NULL); + if (!(yyval.query)) { + YYERROR; + } + } + break; + + case 11: +/* Line 1792 of yacc.c */ +#line 203 "wsp_aqs_parser.y" + { + (yyval.query) = create_query_node(talloc_tos(), eOR, (yyvsp[(1) - (3)].query), (yyvsp[(3) - (3)].query), NULL); + if (!(yyval.query)) { + YYERROR; + } + } + break; + + case 12: +/* Line 1792 of yacc.c */ +#line 209 "wsp_aqs_parser.y" + { + (yyval.query) = create_query_node(talloc_tos(), eNOT, NULL, (yyvsp[(2) - (2)].query), NULL); + if (!(yyval.query)) { + YYERROR; + } + } + break; + + case 13: +/* Line 1792 of yacc.c */ +#line 218 "wsp_aqs_parser.y" + { + (yyval.bas_query) = create_basic_query(talloc_tos(), (yyvsp[(1) - (3)].strval), (yyvsp[(3) - (3)].bas_rest)); + if (!(yyval.bas_query)) { + YYERROR; + } + } + break; + + case 14: +/* Line 1792 of yacc.c */ +#line 226 "wsp_aqs_parser.y" + { + (yyval.strval) = (yyvsp[(1) - (1)].strval); + if (!(yyval.strval)) { + YYERROR; + } + } + break; + + case 15: +/* Line 1792 of yacc.c */ +#line 235 "wsp_aqs_parser.y" + { + (yyval.bas_rest) = create_basic_restr(talloc_tos(), RTPROPERTY, eEQ, (yyvsp[(1) - (1)].value)); + if (!(yyval.bas_rest)) { + YYERROR; + } + } + break; + + case 16: +/* Line 1792 of yacc.c */ +#line 241 "wsp_aqs_parser.y" + { + (yyval.bas_rest) = create_basic_restr(talloc_tos(), RTPROPERTY, (yyvsp[(1) - (2)].prop_op), (yyvsp[(2) - (2)].value)); + if (!(yyval.bas_rest)) { + YYERROR; + } + } + break; + + case 17: +/* Line 1792 of yacc.c */ +#line 247 "wsp_aqs_parser.y" + { + (yyval.bas_rest) = create_basic_restr(talloc_tos(), RTCONTENT, (yyvsp[(1) - (2)].prop_op), (yyvsp[(2) - (2)].value)); + if (!(yyval.bas_rest)) { + YYERROR; + } + } + break; + + case 18: +/* Line 1792 of yacc.c */ +#line 253 "wsp_aqs_parser.y" + { + t_value_holder *holder = talloc_zero(talloc_tos(), t_value_holder); + holder->type = RESTR; + holder->value.restr_tree = (yyvsp[(2) - (3)].restr); + (yyval.bas_rest) = create_basic_restr(talloc_tos(), RTNONE, eEQ, holder); + if (!(yyval.bas_rest)) { + YYERROR; + } + } + break; + + case 19: +/* Line 1792 of yacc.c */ +#line 265 "wsp_aqs_parser.y" + { (yyval.prop_op) = eEQ; } + break; + + case 20: +/* Line 1792 of yacc.c */ +#line 266 "wsp_aqs_parser.y" + { (yyval.prop_op) = eNE; } + break; + + case 21: +/* Line 1792 of yacc.c */ +#line 267 "wsp_aqs_parser.y" + { (yyval.prop_op) = eGE; } + break; + + case 22: +/* Line 1792 of yacc.c */ +#line 268 "wsp_aqs_parser.y" + { (yyval.prop_op) = eLE; } + break; + + case 23: +/* Line 1792 of yacc.c */ +#line 269 "wsp_aqs_parser.y" + { (yyval.prop_op) = eLT; } + break; + + case 24: +/* Line 1792 of yacc.c */ +#line 270 "wsp_aqs_parser.y" + { (yyval.prop_op) = eGT; } + break; + + case 25: +/* Line 1792 of yacc.c */ +#line 274 "wsp_aqs_parser.y" + { (yyval.prop_op) = eSTARTSWITH; } + break; + + case 26: +/* Line 1792 of yacc.c */ +#line 275 "wsp_aqs_parser.y" + { (yyval.prop_op) = eEQUALS; } + break; + + case 27: +/* Line 1792 of yacc.c */ +#line 279 "wsp_aqs_parser.y" + { (yyval.value) = (yyvsp[(1) - (1)].value);} + break; + + case 28: +/* Line 1792 of yacc.c */ +#line 280 "wsp_aqs_parser.y" + { + (yyval.value) = create_value_range(talloc_tos(), (yyvsp[(1) - (3)].value), (yyvsp[(3) - (3)].value)); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 29: +/* Line 1792 of yacc.c */ +#line 286 "wsp_aqs_parser.y" + { + (yyval.value) = create_date_range_shortcut(talloc_tos(), (yyvsp[(1) - (1)].daterange)); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 30: +/* Line 1792 of yacc.c */ +#line 292 "wsp_aqs_parser.y" + { + (yyval.value) = create_size_range_shortcut(talloc_tos(), (yyvsp[(1) - (1)].sizerange)); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 31: +/* Line 1792 of yacc.c */ +#line 301 "wsp_aqs_parser.y" + { (yyval.daterange) = eTODAY; } + break; + + case 32: +/* Line 1792 of yacc.c */ +#line 302 "wsp_aqs_parser.y" + { (yyval.daterange) = eYESTERDAY; } + break; + + case 33: +/* Line 1792 of yacc.c */ +#line 303 "wsp_aqs_parser.y" + { (yyval.daterange) = eTHISWEEK; } + break; + + case 34: +/* Line 1792 of yacc.c */ +#line 304 "wsp_aqs_parser.y" + { (yyval.daterange) = eLASTWEEK; } + break; + + case 35: +/* Line 1792 of yacc.c */ +#line 305 "wsp_aqs_parser.y" + { (yyval.daterange) = eTHISMONTH; } + break; + + case 36: +/* Line 1792 of yacc.c */ +#line 306 "wsp_aqs_parser.y" + { (yyval.daterange) = eTHISMONTH; } + break; + + case 37: +/* Line 1792 of yacc.c */ +#line 307 "wsp_aqs_parser.y" + { (yyval.daterange) = eTHISYEAR; } + break; + + case 38: +/* Line 1792 of yacc.c */ +#line 308 "wsp_aqs_parser.y" + { (yyval.daterange) = eLASTYEAR; } + break; + + case 39: +/* Line 1792 of yacc.c */ +#line 312 "wsp_aqs_parser.y" + { (yyval.sizerange) = eEMPTY; } + break; + + case 40: +/* Line 1792 of yacc.c */ +#line 313 "wsp_aqs_parser.y" + { (yyval.sizerange) = eTINY; } + break; + + case 41: +/* Line 1792 of yacc.c */ +#line 314 "wsp_aqs_parser.y" + { (yyval.sizerange) = eSMALL; } + break; + + case 42: +/* Line 1792 of yacc.c */ +#line 315 "wsp_aqs_parser.y" + { (yyval.sizerange) = eMEDIUM; } + break; + + case 43: +/* Line 1792 of yacc.c */ +#line 316 "wsp_aqs_parser.y" + { (yyval.sizerange) = eLARGE; } + break; + + case 44: +/* Line 1792 of yacc.c */ +#line 317 "wsp_aqs_parser.y" + { (yyval.sizerange) = eHUGE; } + break; + + case 45: +/* Line 1792 of yacc.c */ +#line 318 "wsp_aqs_parser.y" + { (yyval.sizerange) = eGIGANTIC; } + break; + + case 46: +/* Line 1792 of yacc.c */ +#line 322 "wsp_aqs_parser.y" + { + (yyval.value) = create_num_val(talloc_tos(), (yyvsp[(1) - (1)].num)); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 47: +/* Line 1792 of yacc.c */ +#line 328 "wsp_aqs_parser.y" + { + (yyval.value) = create_num_val(talloc_tos(), (yyvsp[(1) - (2)].num) * 1024); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 48: +/* Line 1792 of yacc.c */ +#line 334 "wsp_aqs_parser.y" + { + (yyval.value) = create_num_val( talloc_tos(), (yyvsp[(1) - (2)].num) * 1024 * 1024); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 49: +/* Line 1792 of yacc.c */ +#line 340 "wsp_aqs_parser.y" + { + (yyval.value) = create_num_val(talloc_tos(), (yyvsp[(1) - (2)].num) * 1024 * 1024 * 1024); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 50: +/* Line 1792 of yacc.c */ +#line 346 "wsp_aqs_parser.y" + { + (yyval.value) = create_num_val(talloc_tos(), + (yyvsp[(1) - (2)].num) * 1024 * 1024 * 1024 * 1024); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 51: +/* Line 1792 of yacc.c */ +#line 353 "wsp_aqs_parser.y" + { + (yyval.value) = create_num_val(talloc_tos(), (yyvsp[(1) - (2)].num) * 1000); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 52: +/* Line 1792 of yacc.c */ +#line 359 "wsp_aqs_parser.y" + { + (yyval.value) = create_num_val( talloc_tos(), (yyvsp[(1) - (2)].num) * 1000 * 1000); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 53: +/* Line 1792 of yacc.c */ +#line 365 "wsp_aqs_parser.y" + { + (yyval.value) = create_num_val(talloc_tos(), (yyvsp[(1) - (2)].num) * 1000 * 1000 * 1000); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 54: +/* Line 1792 of yacc.c */ +#line 371 "wsp_aqs_parser.y" + { + (yyval.value) = create_num_val(talloc_tos(), + (yyvsp[(1) - (2)].num) * 1000 * 1000 * 1000 * 1000); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 55: +/* Line 1792 of yacc.c */ +#line 378 "wsp_aqs_parser.y" + { + (yyval.value) = create_bool_val(talloc_tos(), true); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 56: +/* Line 1792 of yacc.c */ +#line 384 "wsp_aqs_parser.y" + { + (yyval.value) = create_num_val(talloc_tos(), false); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 57: +/* Line 1792 of yacc.c */ +#line 390 "wsp_aqs_parser.y" + { + char *tmp_str = talloc_strdup(talloc_tos(), (yyvsp[(1) - (1)].strval)+1); + tmp_str[strlen(tmp_str)-1] = '\0'; + (yyval.value) = create_string_val(talloc_tos(), tmp_str); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 58: +/* Line 1792 of yacc.c */ +#line 398 "wsp_aqs_parser.y" + { + (yyval.value) = create_string_val(talloc_tos(), (yyvsp[(1) - (1)].strval)); + if (!(yyval.value)) { + YYERROR; + } + } + break; + + case 59: +/* Line 1792 of yacc.c */ +#line 406 "wsp_aqs_parser.y" + { + (yyval.restr) = create_restr(talloc_tos(), eVALUE, NULL, NULL, (yyvsp[(1) - (1)].bas_rest)); + if (!(yyval.restr)) { + YYERROR; + } + } + break; + + case 60: +/* Line 1792 of yacc.c */ +#line 412 "wsp_aqs_parser.y" + { + (yyval.restr) = create_restr(talloc_tos(), eAND, (yyvsp[(1) - (3)].restr), (yyvsp[(3) - (3)].restr), NULL); + if (!(yyval.restr)) { + YYERROR; + } + } + break; + + case 61: +/* Line 1792 of yacc.c */ +#line 418 "wsp_aqs_parser.y" + { + (yyval.restr) = create_restr(talloc_tos(), eOR, (yyvsp[(1) - (3)].restr), (yyvsp[(3) - (3)].restr), NULL); + if (!(yyval.restr)) { + YYERROR; + } + } + break; + + +/* Line 1792 of yacc.c */ +#line 2087 "wsp_aqs_parser.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (select, scanner, YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (select, scanner, yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, select, scanner); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp, select, scanner); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (select, scanner, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, select, scanner); + } + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, select, scanner); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +/* Line 2055 of yacc.c */ +#line 425 "wsp_aqs_parser.y" + diff --git a/source4/libcli/wsp/wsp_aqs_parser.h b/source4/libcli/wsp/wsp_aqs_parser.h new file mode 100644 index 0000000..01c4f6f --- /dev/null +++ b/source4/libcli/wsp/wsp_aqs_parser.h @@ -0,0 +1,158 @@ +/* A Bison parser, made by GNU Bison 2.7. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef YY_YY_WSP_AQS_PARSER_H_INCLUDED +# define YY_YY_WSP_AQS_PARSER_H_INCLUDED +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif +/* "%code requires" blocks. */ +/* Line 2058 of yacc.c */ +#line 34 "wsp_aqs_parser.y" + + +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + + + +/* Line 2058 of yacc.c */ +#line 56 "wsp_aqs_parser.h" + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + TOKEN_AND = 259, + TOKEN_OR = 261, + TOKEN_NE = 263, + TOKEN_GE = 265, + TOKEN_LE = 267, + TOKEN_LT = 269, + TOKEN_GT = 271, + TOKEN_NOT = 273, + TOKEN_EQ = 275, + TOKEN_PROP_EQUALS = 277, + TOKEN_STARTS_WITH = 279, + TOKEN_EQUALS = 281, + TOKEN_LPAREN = 282, + TOKEN_RPAREN = 283, + TOKEN_WHERE = 284, + TOKEN_SELECT = 285, + TOKEN_TRUE = 286, + TOKEN_FALSE = 287, + TOKEN_COMMA = 288, + TOKEN_MATCHES = 289, + TOKEN_K = 290, + TOKEN_M = 291, + TOKEN_G = 292, + TOKEN_T = 293, + TOKEN_KB = 294, + TOKEN_MB = 295, + TOKEN_GB = 296, + TOKEN_TB = 297, + TOKEN_RANGE = 298, + TOKEN_TODAY = 299, + TOKEN_YESTERDAY = 300, + TOKEN_THISWEEK = 301, + TOKEN_LASTWEEK = 302, + TOKEN_THISMONTH = 303, + TOKEN_LASTMONTH = 304, + TOKEN_THISYEAR = 305, + TOKEN_LASTYEAR = 306, + TOKEN_EMPTY = 307, + TOKEN_TINY = 308, + TOKEN_SMALL = 309, + TOKEN_MEDIUM = 310, + TOKEN_LARGE = 311, + TOKEN_HUGE = 312, + TOKEN_GIGANTIC = 313, + TOKEN_NUMBER = 314, + TOKEN_IDENTIFIER = 315, + TOKEN_STRING_LITERAL = 316 + }; +#endif + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ +/* Line 2058 of yacc.c */ +#line 51 "wsp_aqs_parser.y" + + char *strval; + int64_t num; + t_value_holder *value; + t_select_stmt *select_stmt; + t_select_stmt *query_stmt; + t_basic_restr *bas_rest; + t_basic_query *bas_query; + t_restr *restr; + t_query *query; + t_col_list *columns; + daterange_type daterange; + sizerange_type sizerange; + t_optype prop_op; + + +/* Line 2058 of yacc.c */ +#line 137 "wsp_aqs_parser.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (t_select_stmt **select, yyscan_t scanner); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !YY_YY_WSP_AQS_PARSER_H_INCLUDED */ diff --git a/source4/libcli/wsp/wsp_aqs_parser.y b/source4/libcli/wsp/wsp_aqs_parser.y new file mode 100644 index 0000000..726d4d3 --- /dev/null +++ b/source4/libcli/wsp/wsp_aqs_parser.y @@ -0,0 +1,425 @@ +/* + * Unix SMB/CIFS implementation. + * + * Window Search Service + * + * Copyright (c) 2016 Noel Power + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +%{ + +#include "includes.h" +#include "libcli/wsp/wsp_aqs.h" +#include "libcli/wsp/wsp_aqs_parser.h" +#include "libcli/wsp/wsp_aqs_lexer.h" + +static int yyerror(t_select_stmt **stmt, yyscan_t scanner, const char *msg) +{ + fprintf(stderr,"Error :%s\n",msg); return 0; +} +%} +%code requires { + +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +} + +%output "wsp_aqs_parser.c" +%defines "wsp_aqs_parser.h" + +%define api.pure +%lex-param { yyscan_t scanner } +%parse-param { t_select_stmt **select } +%parse-param { yyscan_t scanner } + +%union { + char *strval; + int64_t num; + t_value_holder *value; + t_select_stmt *select_stmt; + t_select_stmt *query_stmt; + t_basic_restr *bas_rest; + t_basic_query *bas_query; + t_restr *restr; + t_query *query; + t_col_list *columns; + daterange_type daterange; + sizerange_type sizerange; + t_optype prop_op; +} + +%left "AND" TOKEN_AND +%left "OR" TOKEN_OR +%left "!=" TOKEN_NE +%left ">=" TOKEN_GE +%left "<=" TOKEN_LE +%left "<" TOKEN_LT +%left ">" TOKEN_GT +%right "NOT" TOKEN_NOT +%right "==" TOKEN_EQ +%right ":" TOKEN_PROP_EQUALS + +%right "$<" TOKEN_STARTS_WITH +%right "$=" TOKEN_EQUALS + +%token TOKEN_LPAREN +%token TOKEN_RPAREN +%token TOKEN_AND +%token TOKEN_OR +%token TOKEN_WHERE +%token TOKEN_SELECT +%token TOKEN_TRUE +%token TOKEN_FALSE +%token TOKEN_COMMA +%token TOKEN_STARTS_WITH +%token TOKEN_EQUALS +%token TOKEN_MATCHES +%token TOKEN_K +%token TOKEN_M +%token TOKEN_G +%token TOKEN_T +%token TOKEN_KB +%token TOKEN_MB +%token TOKEN_GB +%token TOKEN_TB +%token TOKEN_RANGE +%token TOKEN_TODAY +%token TOKEN_YESTERDAY +%token TOKEN_THISWEEK +%token TOKEN_LASTWEEK +%token TOKEN_THISMONTH +%token TOKEN_LASTMONTH +%token TOKEN_THISYEAR +%token TOKEN_LASTYEAR +%token TOKEN_EMPTY +%token TOKEN_TINY +%token TOKEN_SMALL +%token TOKEN_MEDIUM +%token TOKEN_LARGE +%token TOKEN_HUGE +%token TOKEN_GIGANTIC + +%token TOKEN_NUMBER +%token TOKEN_IDENTIFIER +%token TOKEN_STRING_LITERAL + +%type prop +%type basic_restr +%type restr +%type basic_query +%type query +%type cols +%type col +%type select_stmt +%type simple_value +%type value +%type date_shortcut +%type property_op +%type content_op +%type size_shortcut + +%% + +input: + select_stmt { + *select = $1; + } +; + +select_stmt: + TOKEN_SELECT cols[C] TOKEN_WHERE query[Q] { + $$ = create_select(talloc_tos(), $C, $Q ); + if (!$$) { + YYERROR; + } + } + | query[Q] { + $$ = create_select(talloc_tos(), NULL, $Q ); + if (!$$) { + YYERROR; + } + } + ; + +cols : + col[C] { + $$ = create_cols(talloc_tos(), $1, NULL); + if (!$$) { + YYERROR; + } + } + | col[C] TOKEN_COMMA cols[CS] { + $$ = create_cols(talloc_tos(), $C, $CS); + if (!$$) { + YYERROR; + } + } + ; + +col: + TOKEN_IDENTIFIER[I] { + $$ = $I; + if (!$$) { + YYERROR; + } + } + ; + +query: + basic_query { + $$ = create_query_node(talloc_tos(), eVALUE, NULL, NULL, $1); + if (!$$) { + YYERROR; + } + } + | TOKEN_LPAREN query[Q] TOKEN_RPAREN { + $$ = $Q; + if (!$$) { + YYERROR; + } + } + | query[L] TOKEN_AND query[R] { + $$ = create_query_node(talloc_tos(), eAND, $L, $R, NULL); + if (!$$) { + YYERROR; + } + } + | query[L] TOKEN_OR query[R] { + $$ = create_query_node(talloc_tos(), eOR, $L, $R, NULL); + if (!$$) { + YYERROR; + } + } + | TOKEN_NOT query[R] { + $$ = create_query_node(talloc_tos(), eNOT, NULL, $R, NULL); + if (!$$) { + YYERROR; + } + } + ; + +basic_query: + prop[P] TOKEN_PROP_EQUALS basic_restr[V] { + $$ = create_basic_query(talloc_tos(), $P, $V); + if (!$$) { + YYERROR; + } + } + ; + +prop: TOKEN_IDENTIFIER[I] { + $$ = $I; + if (!$$) { + YYERROR; + } + } + ; + +basic_restr: + value[V] { + $$ = create_basic_restr(talloc_tos(), RTPROPERTY, eEQ, $V); + if (!$$) { + YYERROR; + } + } + | property_op[P] value[T] { + $$ = create_basic_restr(talloc_tos(), RTPROPERTY, $P, $T); + if (!$$) { + YYERROR; + } + } + | content_op[P] value[T] { + $$ = create_basic_restr(talloc_tos(), RTCONTENT, $P, $T); + if (!$$) { + YYERROR; + } + } + | TOKEN_LPAREN restr[R] TOKEN_RPAREN { + t_value_holder *holder = talloc_zero(talloc_tos(), t_value_holder); + holder->type = RESTR; + holder->value.restr_tree = $R; + $$ = create_basic_restr(talloc_tos(), RTNONE, eEQ, holder); + if (!$$) { + YYERROR; + } + } + ; + +property_op: + TOKEN_EQ { $$ = eEQ; } + | TOKEN_NE { $$ = eNE; } + | TOKEN_GE { $$ = eGE; } + | TOKEN_LE { $$ = eLE; } + | TOKEN_LT { $$ = eLT; } + | TOKEN_GT { $$ = eGT; } + ; + +content_op: + TOKEN_STARTS_WITH { $$ = eSTARTSWITH; } + | TOKEN_EQUALS { $$ = eEQUALS; } + ; + +value: + simple_value[V] { $$ = $V;} + | simple_value[L] TOKEN_RANGE simple_value[R] { + $$ = create_value_range(talloc_tos(), $L, $R); + if (!$$) { + YYERROR; + } + } + | date_shortcut[D] { + $$ = create_date_range_shortcut(talloc_tos(), $D); + if (!$$) { + YYERROR; + } + } + | size_shortcut[S] { + $$ = create_size_range_shortcut(talloc_tos(), $S); + if (!$$) { + YYERROR; + } + } + ; + +date_shortcut: + TOKEN_TODAY { $$ = eTODAY; } + | TOKEN_YESTERDAY { $$ = eYESTERDAY; } + | TOKEN_THISWEEK { $$ = eTHISWEEK; } + | TOKEN_LASTWEEK { $$ = eLASTWEEK; } + | TOKEN_THISMONTH { $$ = eTHISMONTH; } + | TOKEN_LASTMONTH { $$ = eTHISMONTH; } + | TOKEN_THISYEAR { $$ = eTHISYEAR; } + | TOKEN_LASTYEAR { $$ = eLASTYEAR; } + ; + +size_shortcut: + TOKEN_EMPTY { $$ = eEMPTY; } + | TOKEN_TINY { $$ = eTINY; } + | TOKEN_SMALL { $$ = eSMALL; } + | TOKEN_MEDIUM { $$ = eMEDIUM; } + | TOKEN_LARGE { $$ = eLARGE; } + | TOKEN_HUGE { $$ = eHUGE; } + | TOKEN_GIGANTIC { $$ = eGIGANTIC; } + ; + +simple_value: + TOKEN_NUMBER[N] { + $$ = create_num_val(talloc_tos(), $N); + if (!$$) { + YYERROR; + } + } + | TOKEN_NUMBER[N] TOKEN_K { + $$ = create_num_val(talloc_tos(), $N * 1024); + if (!$$) { + YYERROR; + } + } + | TOKEN_NUMBER[N] TOKEN_M { + $$ = create_num_val( talloc_tos(), $N * 1024 * 1024); + if (!$$) { + YYERROR; + } + } + | TOKEN_NUMBER[N] TOKEN_G { + $$ = create_num_val(talloc_tos(), $N * 1024 * 1024 * 1024); + if (!$$) { + YYERROR; + } + } + | TOKEN_NUMBER[N] TOKEN_T { + $$ = create_num_val(talloc_tos(), + $N * 1024 * 1024 * 1024 * 1024); + if (!$$) { + YYERROR; + } + } + | TOKEN_NUMBER[N] TOKEN_KB { + $$ = create_num_val(talloc_tos(), $N * 1000); + if (!$$) { + YYERROR; + } + } + | TOKEN_NUMBER[N] TOKEN_MB { + $$ = create_num_val( talloc_tos(), $N * 1000 * 1000); + if (!$$) { + YYERROR; + } + } + | TOKEN_NUMBER[N] TOKEN_GB { + $$ = create_num_val(talloc_tos(), $N * 1000 * 1000 * 1000); + if (!$$) { + YYERROR; + } + } + | TOKEN_NUMBER[N] TOKEN_TB { + $$ = create_num_val(talloc_tos(), + $N * 1000 * 1000 * 1000 * 1000); + if (!$$) { + YYERROR; + } + } + | TOKEN_TRUE { + $$ = create_bool_val(talloc_tos(), true); + if (!$$) { + YYERROR; + } + } + | TOKEN_FALSE { + $$ = create_num_val(talloc_tos(), false); + if (!$$) { + YYERROR; + } + } + | TOKEN_STRING_LITERAL[S] { + char *tmp_str = talloc_strdup(talloc_tos(), $S+1); + tmp_str[strlen(tmp_str)-1] = '\0'; + $$ = create_string_val(talloc_tos(), tmp_str); + if (!$$) { + YYERROR; + } + } + | TOKEN_IDENTIFIER[I] { + $$ = create_string_val(talloc_tos(), $I); + if (!$$) { + YYERROR; + } + } + ; + +restr: basic_restr[V] { + $$ = create_restr(talloc_tos(), eVALUE, NULL, NULL, $V); + if (!$$) { + YYERROR; + } + } + | restr[L] TOKEN_AND restr[R] { + $$ = create_restr(talloc_tos(), eAND, $L, $R, NULL); + if (!$$) { + YYERROR; + } + } + | restr[L] TOKEN_OR restr[R] { + $$ = create_restr(talloc_tos(), eOR, $L, $R, NULL); + if (!$$) { + YYERROR; + } + } + ; +%% diff --git a/source4/libcli/wsp/wsp_cli.c b/source4/libcli/wsp/wsp_cli.c new file mode 100644 index 0000000..f313d89 --- /dev/null +++ b/source4/libcli/wsp/wsp_cli.c @@ -0,0 +1,1794 @@ +/* + * Unix SMB/CIFS implementation. + * + * Window Search Service + * + * Copyright (c) 2016 Noel Power + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" +#include "bin/default/librpc/gen_ndr/ndr_wsp.h" +#include "libcli/wsp/wsp_cli.h" +#include "param/param.h" +#include "dcerpc.h" +#include "libcli/raw/interfaces.h" +#include "auth/credentials/credentials.h" +#include "libcli/libcli.h" +#include "libcli/smb/tstream_smbXcli_np.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" +#include "libcli/smb/smbXcli_base.h" +#include "smb_composite/smb_composite.h" +#include "lib/cmdline/popt_common.h" +#include "libcli/resolve/resolve.h" +#include "librpc/rpc/dcerpc_raw.h" +#include +#include + +#define MSG_HDR_SIZE 16 +#if __WORDSIZE == 64 +static const uint32_t CLIENTVERSION = 0x00010700; +#else +static const uint32_t CLIENTVERSION = 0x00000700; +#endif + +static int32_t scope_flags_vector[] = {0x00000001}; +static const char * root_scope_string_vector[] = {"\\"}; + +/* sets sensible defaults */ +static void init_wsp_prop(struct wsp_cdbprop *prop) +{ + prop->dbpropoptions = 0x0000000; + prop->dbpropstatus = 0x0000000; + ZERO_STRUCT(prop->colid.guid); /* just in case */ + ZERO_STRUCT(prop->vvalue); /* just in case */ + prop->colid.ekind = DBKIND_GUID_PROPID; + prop->colid.uiid = 0x00000000; +} + + +static void create_restriction_array(TALLOC_CTX *ctx, + struct wsp_crestriction **pelements, + uint32_t nnodes) +{ + struct wsp_crestriction *elements = talloc_zero_array(ctx, + struct wsp_crestriction, + nnodes); + *pelements = elements; +} + + +static void create_noderestriction(TALLOC_CTX *ctx, + struct wsp_cnoderestriction *pnode, + uint32_t nnodes) +{ + pnode->cnode = nnodes; + create_restriction_array(ctx, &pnode->panode, nnodes); +} + +static void fill_sortarray(TALLOC_CTX *ctx, struct wsp_csort **dest, + struct wsp_csort *src, uint32_t num) +{ + int i; + struct wsp_csort *psort = talloc_zero_array(ctx, struct wsp_csort, + num); + for (i = 0; i < num; i++) { + psort[i] = src[i]; + } + *dest = psort; +} + + + +static bool set_fullpropspec(TALLOC_CTX *ctx, struct wsp_cfullpropspec *prop, + const char* propname, uint32_t kind) +{ + struct GUID guid; + const struct full_propset_info *prop_info; + ZERO_STRUCT(guid); + prop_info = get_propset_info_with_guid(propname, &guid); + if (!prop_info) { + /* #FIXME error handling */ + DBG_ERR("Failed to handle property named %s\n", + propname); + return false; + } + prop->guidpropset = guid; + prop->ulkind = kind; + if (kind == PRSPEC_LPWSTR) { + prop->name_or_id.propname.vstring = talloc_strdup(ctx, + propname); + prop->name_or_id.propname.len = strlen(propname); + } else { + prop->name_or_id.prspec = prop_info->id; + } + return true; +} + +static int32_t get_value_size(bool is_64bit) { + int32_t value_size = 0x10; + if (is_64bit) { + value_size = 0x18; + } + return value_size; +} + +struct binding +{ + uint32_t status_off; + uint32_t value_off; + uint32_t len_off; +}; + +static bool set_ctablecolumn(TALLOC_CTX *ctx, struct wsp_ctablecolumn *tablecol, + const char* propname, struct binding *offsets, + bool is_64bit) +{ + struct wsp_cfullpropspec *prop = &tablecol->propspec; + + if (!set_fullpropspec(ctx, prop, propname, PRSPEC_PROPID)) { + return false; + } + tablecol->vtype =VT_VARIANT ; + tablecol->aggregateused = 1; + tablecol->valueused = 1; + tablecol->valueoffset.value = offsets->value_off; + tablecol->valuesize.value = get_value_size(is_64bit); + tablecol->statusused = 1; + tablecol->statusoffset.value = offsets->status_off; + tablecol->lengthused = 1; + tablecol->lengthoffset.value = offsets->len_off; + return true; +} + + +static void fill_uint32_vec(TALLOC_CTX* ctx, + uint32_t **pdest, + uint32_t* ivector, uint32_t elems) +{ + int i; + uint32_t *dest = talloc_zero_array(ctx, uint32_t, elems); + for ( i = 0; i < elems; i++ ) { + dest[ i ] = ivector[ i ]; + } + *pdest = dest; +} + +static void init_propset1(TALLOC_CTX* tmp_ctx, + struct wsp_cdbpropset *propertyset) +{ + int i; + + GUID_from_string(DBPROPSET_FSCIFRMWRK_EXT, + &propertyset->guidpropertyset); + + propertyset->cproperties = 4; + propertyset->aprops = + talloc_zero_array(tmp_ctx, struct wsp_cdbprop, + propertyset->cproperties); + /* initialise first 4 props */ + for( i = 0; i < propertyset->cproperties; i++) { + init_wsp_prop(&propertyset->aprops[i]); + } + + /* set value prop[0] */ + propertyset->aprops[0].dbpropid = DBPROP_CI_CATALOG_NAME; + set_variant_lpwstr(tmp_ctx, &propertyset->aprops[0].vvalue, + "Windows\\SYSTEMINDEX"); + /* set value prop[1] */ + propertyset->aprops[1].dbpropid = DBPROP_CI_QUERY_TYPE; + set_variant_i4(tmp_ctx, &propertyset->aprops[1].vvalue, + CINORMAL); + /* set value prop[2] */ + propertyset->aprops[2].dbpropid = DBPROP_CI_SCOPE_FLAGS; + set_variant_i4_vector(tmp_ctx, &propertyset->aprops[2].vvalue, + scope_flags_vector, ARRAY_SIZE(scope_flags_vector)); + /* set value prop[3] */ + propertyset->aprops[3].dbpropid = DBPROP_CI_INCLUDE_SCOPES; + set_variant_lpwstr_vector(tmp_ctx, + &propertyset->aprops[3].vvalue, + root_scope_string_vector, + ARRAY_SIZE(root_scope_string_vector)); +} + +static void init_propset2(TALLOC_CTX* tmp_ctx, + struct wsp_cdbpropset *propertyset, + const char* server) +{ + int i; + + GUID_from_string(DBPROPSET_CIFRMWRKCORE_EXT, + &propertyset->guidpropertyset); + + propertyset->cproperties = 1; + propertyset->aprops = + talloc_zero_array(tmp_ctx, struct wsp_cdbprop, + propertyset->cproperties); + /* initialise first 1 props */ + for( i = 0; i < propertyset->cproperties; i++) { + init_wsp_prop(&propertyset->aprops[i]); + } + + /* set value prop[0] */ + propertyset->aprops[0].dbpropid = DBPROP_MACHINE; + set_variant_bstr(tmp_ctx, &propertyset->aprops[0].vvalue, + server); +} + +static void init_apropset0(TALLOC_CTX* tmp_ctx, + struct wsp_cdbpropset *propertyset) +{ + int i; + + GUID_from_string(DBPROPSET_MSIDXS_ROWSETEXT, + &propertyset->guidpropertyset); + + propertyset->cproperties = 7; + propertyset->aprops = + talloc_zero_array(tmp_ctx, struct wsp_cdbprop, + propertyset->cproperties); + /* initialise props */ + for( i = 0; i < propertyset->cproperties; i++) { + init_wsp_prop(&propertyset->aprops[i]); + } + + /* set value prop[0] MSIDXSPROP_ROWSETQUERYSTATUS where is this specified ? */ + propertyset->aprops[0].dbpropid = 0x00000002; + set_variant_i4(tmp_ctx, &propertyset->aprops[0].vvalue, 0x00000000); + + /* set value prop[1] MSIDXSPROP_COMMAND_LOCALE_STRING */ + propertyset->aprops[1].dbpropid = 0x00000003; + set_variant_bstr(tmp_ctx, &propertyset->aprops[1].vvalue, + "en-ie"); + /* set value prop[2] MSIDXSPROP_QUERY_RESTRICTION */ + propertyset->aprops[2].dbpropid = 0x00000004; + set_variant_bstr(tmp_ctx, &propertyset->aprops[2].vvalue, + ""); + /* set value prop[3] MSIDXSPROP_PARSE_TREE */ + propertyset->aprops[3].dbpropid = 0x00000005; + set_variant_bstr(tmp_ctx, &propertyset->aprops[3].vvalue, + ""); + /* set value prop[4] MSIDXSPROP_MAX_RANK */ + propertyset->aprops[4].dbpropid = 0x00000006; + set_variant_i4(tmp_ctx, &propertyset->aprops[4].vvalue, 0x00000000); + /* set value prop[5] MSIDXSPROP_RESULTS_FOUND */ + propertyset->aprops[5].dbpropid = 0x00000007; + set_variant_i4(tmp_ctx, &propertyset->aprops[5].vvalue, 0x00000000); + /* set value prop[6] ?? */ + propertyset->aprops[6].dbpropid = 0x00000008; + set_variant_i4(tmp_ctx, &propertyset->aprops[6].vvalue, 0x00000000); +} + +static void init_apropset1(TALLOC_CTX* tmp_ctx, + struct wsp_cdbpropset *propertyset) +{ + int i; + GUID_from_string(DBPROPSET_QUERYEXT, + &propertyset->guidpropertyset); + + propertyset->cproperties = 0x0000000B; + propertyset->aprops = + talloc_zero_array(tmp_ctx, struct wsp_cdbprop, + propertyset->cproperties); + /* init properties */ + for( i = 0; i < propertyset->cproperties; i++) { + init_wsp_prop(&propertyset->aprops[i]); + } + + /* set value prop[0] */ + propertyset->aprops[0].dbpropid = DBPROP_USECONTENTINDEX; + set_variant_vt_bool(tmp_ctx, &propertyset->aprops[0].vvalue, false); + /* set value prop[1] */ + propertyset->aprops[1].dbpropid = DBPROP_DEFERNONINDEXEDTRIMMING; + set_variant_vt_bool(tmp_ctx, &propertyset->aprops[1].vvalue, false); + /* set value prop[2] */ + propertyset->aprops[2].dbpropid = DBPROP_USEEXTENDEDDBTYPES; + set_variant_vt_bool(tmp_ctx, &propertyset->aprops[2].vvalue, false); + /* set value prop[3] */ + propertyset->aprops[3].dbpropid = DBPROP_IGNORENOISEONLYCLAUSES; + set_variant_vt_bool(tmp_ctx, &propertyset->aprops[3].vvalue, false); + /* set value prop[4] */ + propertyset->aprops[4].dbpropid = DBPROP_GENERICOPTIONS_STRING; + set_variant_bstr(tmp_ctx, &propertyset->aprops[4].vvalue, ""); + /* set value prop[5] */ + propertyset->aprops[5].dbpropid = DBPROP_DEFERCATALOGVERIFICATION; + set_variant_vt_bool(tmp_ctx, &propertyset->aprops[5].vvalue, false); + /* set value prop[6] */ + propertyset->aprops[6].dbpropid = DBPROP_IGNORESBRI; + set_variant_vt_bool(tmp_ctx, &propertyset->aprops[6].vvalue, false); + /* set value prop[7] */ + propertyset->aprops[7].dbpropid = DBPROP_GENERATEPARSETREE; + set_variant_vt_bool(tmp_ctx, &propertyset->aprops[7].vvalue, false); + /* set value prop[8] */ + propertyset->aprops[8].dbpropid = DBPROP_FREETEXTANYTERM; + set_variant_vt_bool(tmp_ctx, &propertyset->aprops[8].vvalue, false); + /* set value prop[9] */ + propertyset->aprops[9].dbpropid = DBPROP_FREETEXTUSESTEMMING; + set_variant_vt_bool(tmp_ctx, &propertyset->aprops[9].vvalue, false); + /* set value prop[10] */ + propertyset->aprops[10].dbpropid = 0x0000000f; /* ??? */ + set_variant_vt_bool(tmp_ctx, &propertyset->aprops[10].vvalue, false); +} + +static void init_apropset2(TALLOC_CTX* tmp_ctx, + struct wsp_cdbpropset *propertyset, + const char* server) +{ + int i; + GUID_from_string(DBPROPSET_CIFRMWRKCORE_EXT, + &propertyset->guidpropertyset); + + propertyset->cproperties = 0x00000001; + propertyset->aprops = + talloc_zero_array(tmp_ctx, struct wsp_cdbprop, + propertyset->cproperties); + /* init properties */ + for( i = 0; i < propertyset->cproperties; i++) { + init_wsp_prop(&propertyset->aprops[i]); + } + + /* set value prop[0] */ + propertyset->aprops[0].dbpropid = DBPROP_MACHINE; + set_variant_bstr(tmp_ctx, &propertyset->aprops[0].vvalue, server); + +} + + +static void init_apropset3(TALLOC_CTX* tmp_ctx, + struct wsp_cdbpropset *propertyset) +{ + int i; + + GUID_from_string(DBPROPSET_FSCIFRMWRK_EXT, + &propertyset->guidpropertyset); + + propertyset->cproperties = 0x00000003; + propertyset->aprops = + talloc_zero_array(tmp_ctx, struct wsp_cdbprop, + propertyset->cproperties); + /* init properties */ + for( i = 0; i < propertyset->cproperties; i++) { + init_wsp_prop(&propertyset->aprops[i]); + } + + /* set value prop[0] */ + propertyset->aprops[0].dbpropid = DBPROP_CI_INCLUDE_SCOPES; + set_variant_array_bstr(tmp_ctx, &propertyset->aprops[0].vvalue, + root_scope_string_vector, + ARRAY_SIZE(root_scope_string_vector)); + /* set value prop[1] */ + propertyset->aprops[1].dbpropid = DBPROP_CI_SCOPE_FLAGS; + set_variant_array_i4(tmp_ctx, &propertyset->aprops[1].vvalue, + scope_flags_vector, + ARRAY_SIZE(scope_flags_vector)); + /* set value prop[2] */ + propertyset->aprops[2].dbpropid = DBPROP_CI_CATALOG_NAME; + set_variant_bstr(tmp_ctx, &propertyset->aprops[2].vvalue, + "Windows\\SYSTEMINDEX"); +} + +void init_connectin_request(TALLOC_CTX *ctx, + struct wsp_request* request, + const char* clientmachine, + const char* clientuser, + const char* server) +{ + enum ndr_err_code err; + struct connectin_propsets *props = + talloc_zero(ctx, struct connectin_propsets); + struct connectin_extpropsets *ext_props = + talloc_zero(ctx, struct connectin_extpropsets) ; + DATA_BLOB props_blob; + struct ndr_push *ndr_props; + struct wsp_cpmconnectin *connectin = &request->message.cpmconnect; + int ndr_flags = NDR_SCALARS | NDR_BUFFERS; + + request->header.msg = CPMCONNECT; + connectin->iclientversion = CLIENTVERSION; + connectin->fclientisremote = 0x00000001; + connectin->machinename = clientmachine; + connectin->username = clientuser; + props->cpropsets = 2; + + /* =================== */ + /* set up PropertySet1 */ + /* =================== */ + init_propset1(ctx, &props->propertyset1); + + /* =================== */ + /* set up PropertySet2 */ + /* =================== */ + init_propset2(ctx, &props->propertyset2, server); + /* 4 ExtPropSets */ + ext_props->cextpropset = 4; + ext_props->apropertysets = talloc_zero_array(ctx, struct wsp_cdbpropset, + ext_props->cextpropset); + + /* ======================= */ + /* set up aPropertySets[0] */ + /* ======================= */ + init_apropset0(ctx, &ext_props->apropertysets[0]); + + /* ======================= */ + /* set up aPropertySets[1] */ + /* ======================= */ + init_apropset1(ctx, &ext_props->apropertysets[1]); + + /* ======================= */ + /* set up aPropertySets[2] */ + /* ======================= */ + init_apropset2(ctx, &ext_props->apropertysets[2], server); + + /* ======================= */ + /* set up aPropertySets[3] */ + /* ======================= */ + init_apropset3(ctx, &ext_props->apropertysets[3]); + + /* we also have to fill the opaque blobs that contain the propsets */ + ndr_props = ndr_push_init_ctx(ctx); + + /* first connectin_propsets */ + err = ndr_push_connectin_propsets(ndr_props, ndr_flags, props); + if (err) { + DBG_ERR("Failed to push propset, error %d\n", err); + goto out; + } + props_blob = ndr_push_blob(ndr_props); + connectin->cbblob1 = props_blob.length; + connectin->propsets = talloc_zero_array(ctx, uint8_t, + connectin->cbblob1); + memcpy(connectin->propsets, props_blob.data, props_blob.length); + + /* then connectin_extpropsets */ + TALLOC_FREE(ndr_props); + ndr_props = ndr_push_init_ctx(ctx); + err = ndr_push_connectin_extpropsets(ndr_props, ndr_flags, ext_props); + + if (err) { + DBG_ERR("Failed to push extpropset, error %d\n", err); + goto out; + } + + props_blob = ndr_push_blob(ndr_props); + connectin->cbblob2 = props_blob.length; + connectin->extpropsets = talloc_zero_array(ctx, uint8_t, + connectin->cbblob2); + memcpy(connectin->extpropsets, props_blob.data, props_blob.length); + TALLOC_FREE(ndr_props); +out: + return; +} + +void create_seekat_getrows_request(TALLOC_CTX * ctx, + struct wsp_request* request, + bool is_64bit, + uint32_t cursor, + uint32_t bookmark, + uint32_t skip, + uint32_t rows, + uint32_t cbreserved, + uint64_t client_buf_addr, + uint32_t cbrowwidth, + uint32_t fbwdfetch) +{ + struct wsp_cpmgetrowsin *getrows = &request->message.cpmgetrows; + request->header.msg = CPMGETROWS; + getrows->hcursor = cursor; + getrows->crowstotransfer = rows; + getrows->cbrowWidth = cbrowwidth; + getrows->cbreadbuffer = 0x00004000; + + getrows->ulclientbase = client_buf_addr; + if (is_64bit) { + uint32_t hi = client_buf_addr >> 32; + request->header.ulreserved2 = hi; + } + getrows->cbreserved = cbreserved; + getrows->fbwdfetch = fbwdfetch; + getrows->etype = EROWSEEKAT; + getrows->chapt = 0; + getrows->seekdescription.crowseekat.bmkoffset = bookmark; + getrows->seekdescription.crowseekat.cskip = skip; + getrows->seekdescription.crowseekat.hregion = 0; +} + +static bool dummy_pull(TALLOC_CTX *ctx, + uint16_t type, + uint8_t *address, + uint32_t len, + struct wsp_cbasestoragevariant *val) +{ + return true; +} + +static bool pull_1byte_value(TALLOC_CTX *ctx, + uint16_t type, + uint8_t *address, + uint32_t len, + struct wsp_cbasestoragevariant *val) +{ + if (len < 1) { + return false; + } + val->vtype = type; + val->vvalue.vt_ui1 = (uint8_t)*(address); + DBG_INFO("\tval 0x%x\n", val->vvalue.vt_ui1); + return true; +} + +static bool pull_2byte_value(TALLOC_CTX *ctx, + uint16_t type, + uint8_t *address, + uint32_t len, + struct wsp_cbasestoragevariant *val) +{ + if (len < 2) { + return false; + } + val->vtype = type; + val->vvalue.vt_ui2 = SVALS(address, 0); + if (type == VT_BOOL) { + DBG_INFO("\tval %s (0x%x)\n",val->vvalue.vt_bool == 0xFFFF ? "true" : "false", val->vvalue.vt_bool ); + } else { + DBG_INFO("\tval 0x%x\n", val->vvalue.vt_i2); + } + return true; +} + +static bool pull_4byte_value(TALLOC_CTX *ctx, + uint16_t type, + uint8_t *address, + uint32_t len, + struct wsp_cbasestoragevariant *val) +{ + if (len < 4) { + return false; + } + val->vtype = type; + val->vvalue.vt_ui4 = IVALS(address, 0); + DBG_INFO("\tval 0x%x\n", val->vvalue.vt_i4); + return true; +} + +static bool pull_8byte_value(TALLOC_CTX *ctx, + uint16_t type, + uint8_t *address, + uint32_t len, + struct wsp_cbasestoragevariant *val) +{ + struct wsp_hyper *p_hyper = &val->vvalue.vt_ui8; + uint64_t hyper; + + if (len < 8) { + return false; + } + + val->vtype = type; + hyper = BVAL(address, 0); + uint64_to_wsp_hyper(hyper, p_hyper); + DBG_INFO("\tval 0x%" PRIx64 "\n", hyper); + return true; +} + +static bool pull_nullterm_string_value(TALLOC_CTX *ctx, + uint16_t type, + uint8_t *address, + uint32_t len, + struct wsp_cbasestoragevariant *val) +{ + enum ndr_err_code err; + struct ndr_pull *ndr_pull; + int ndr_flags = NDR_SCALARS | NDR_BUFFERS; + const char *string; + DATA_BLOB variant_blob = data_blob_null; + variant_blob.data = address; + variant_blob.length = len; + ndr_pull = ndr_pull_init_blob(&variant_blob, ctx); + ndr_set_flags(&ndr_pull->flags, LIBNDR_FLAG_STR_NULLTERM); + err = ndr_pull_string(ndr_pull, ndr_flags, &string); + if (err) { + DBG_ERR("error unmarshalling string from %p\n", variant_blob.data ); + return false; + } else { + DBG_INFO("\tstring val ->>>%s<<<-\n", string ); + val->vtype = type; + val->vvalue.vt_lpwstr.value = string; + } + return true; +} + +static struct value_only_handler { + uint16_t vtype; + bool (*pull_fn)(TALLOC_CTX *ctx, + uint16_t type, + uint8_t *address, + uint32_t len, + struct wsp_cbasestoragevariant *val); +} variant_value_only_handlers[] = { + {VT_EMPTY, dummy_pull}, + {VT_NULL, dummy_pull}, + {VT_I1, pull_1byte_value}, + {VT_UI1, pull_1byte_value}, + {VT_I2, pull_2byte_value}, + {VT_UI2, pull_2byte_value}, + {VT_BOOL, pull_2byte_value}, + {VT_I4, pull_4byte_value}, + {VT_UI4, pull_4byte_value}, + {VT_R4, pull_4byte_value}, + {VT_INT, pull_4byte_value}, + {VT_UINT, pull_4byte_value}, + {VT_ERROR, pull_4byte_value}, + {VT_DATE, pull_8byte_value}, + {VT_R8, pull_8byte_value}, + {VT_UI8, pull_8byte_value}, + {VT_I8, pull_8byte_value}, + {VT_FILETIME, pull_8byte_value}, + {VT_LPWSTR, pull_nullterm_string_value}, +}; + +static struct value_only_handler *get_value_handler(uint16_t vtype) +{ + int i; + for (i = 0; i < ARRAY_SIZE(variant_value_only_handlers); i++) { + if (variant_value_only_handlers[i].vtype == vtype) { + return &variant_value_only_handlers[i]; + } + } + return NULL; +} + +static enum ndr_err_code process_fixed_area_val(TALLOC_CTX *ctx, + struct value_only_handler *pull_handler, + bool is_64bit, + uint16_t vtype, + uint32_t len, + uint8_t *rowbuf_start, + uint8_t *value_start, + uint64_t client_buf_base_addr, + struct wsp_cbasestoragevariant *col) +{ + uint8_t *pull_address; + uint8_t buf_offset; + uint32_t pos = 0; + enum ndr_err_code err = NDR_ERR_SUCCESS; + + if (is_variable_size(vtype)) { + if (is_64bit) { + buf_offset = BVAL(value_start, pos); + pos +=8; + } else { + buf_offset = IVAL(value_start, pos); + pos +=4; + } + pull_address = + rowbuf_start + (buf_offset - client_buf_base_addr); + } else { + /* + * read a fixed type from the column fixed size area + * at the begining of the rows buffer + */ + pull_address = value_start; + } + if (!pull_handler->pull_fn(ctx, vtype, pull_address, len, col)) { + err = NDR_ERR_VALIDATE; + DBG_ERR("failed to extract variant value only for type %s\n", + get_vtype_name(vtype)); + } + return err; +} + +static enum ndr_err_code process_variant_val( + TALLOC_CTX *ctx, + struct value_only_handler *pull_handler, + bool is_64bit, + uint16_t vtype, + uint32_t len, + uint8_t *rows_buf_start, + uint32_t rows_buf_len, + uint8_t *value_start, + uint64_t client_buf_base_addr, + struct wsp_cbasestoragevariant *col) +{ + uint8_t *pull_address; + uint64_t buf_offset; + enum ndr_err_code err = NDR_ERR_SUCCESS; + uint32_t pos = 0; + /* + * variant column where the 'real' type is contained in the + * CTableVariant like structure + */ + DBG_INFO("\n"); + DBG_INFO("\tcrowvariant contains %s \n", + get_vtype_name(vtype)); + + if (is_variable_size(vtype)) { + if (is_64bit) { + buf_offset = BVAL(value_start, pos); + pos +=8; + } else { + buf_offset = IVAL(value_start, pos); + pos +=4; + } + /* + * In 32 bit mode len as calculated from the len + * (and this is what the MS-WSP example shows) + * In 64 bit mode len seems sometimes to have the value 0x32 :/ + * and therefore not the lenght we need. + * However these strings are NULL terminated so we + * should be ok. (#TODO investigate more) + */ + if (vtype == VT_LPWSTR) { + /* make sure we don't overrun end of the buff */ + len = rows_buf_len - (buf_offset - client_buf_base_addr); + } + pull_address = rows_buf_start + (buf_offset - client_buf_base_addr); + + } else if ((vtype & VT_VECTOR) == VT_VECTOR) { + int count; + uint64_t addr; + /* + * instead of just an offset we have a count followed + * by an array of uint32_t | unint64_t offsets + */ + uint64_t vec_count; + + /* currently we only support vector of strings */ + if (vtype != (VT_LPWSTR | VT_VECTOR)) { + err = NDR_ERR_VALIDATE; + DBG_ERR("unsupported type %s\n", + get_vtype_name(vtype)); + goto out; + } + /* address of offsets */ + if (is_64bit) { + /* + * maybe this isn't a 64bit value but instead + * due to alignment ? + */ + vec_count = BVAL(value_start, pos); + pos += 8; + + buf_offset = BVAL(value_start, pos); + pos +=8; + } else { + vec_count = IVAL(value_start, pos); + pos += 4; + + buf_offset = IVAL(value_start, pos); + pos +=4; + } + + col->vtype = vtype; + col->vvalue.vt_lpwstr_v.vvector_data = + talloc_zero_array(ctx, + struct vt_lpwstr, + vec_count); + col->vvalue.vt_lpwstr_v.vvector_elements = vec_count; + + addr = buf_offset - client_buf_base_addr; + for (count= 0; count < vec_count; count++) { + uint64_t vec_item_offset; + struct wsp_cbasestoragevariant tmp; + if (is_64bit) { + vec_item_offset = + BVAL(rows_buf_start, + addr); + addr += 8; + } else { + vec_item_offset = + IVAL(rows_buf_start, + addr); + addr += 4; + } + pull_address = + rows_buf_start + (vec_item_offset - client_buf_base_addr); + len = rows_buf_len - (vec_item_offset - client_buf_base_addr); + if (!pull_handler->pull_fn(ctx, + vtype & ~VT_VECTOR, + pull_address, + len, + &tmp)) { + err = NDR_ERR_VALIDATE; + DBG_ERR("failed to extract vector variant value only for type %s\n", get_vtype_name(vtype & ~VT_VECTOR)); + goto out; + } + col->vvalue.vt_lpwstr_v.vvector_data[count] = + tmp.vvalue.vt_lpwstr; + } + goto out; + } else { + uint32_t remaining; + pull_address = value_start; + /* make sure we have enough space in buffer */ + //if (rows_buf_len - (pull_address - rows_buf_start) < len) { + remaining = rows_buf_len - (pull_address - rows_buf_start); + if (remaining < len) { + err = NDR_ERR_VALIDATE; + DBG_ERR("not enough bytes left to extract %s from.\n", get_vtype_name(vtype & ~VT_VECTOR)); + goto out; + + } + } + if (!pull_handler->pull_fn(ctx, vtype, pull_address, len, col)) { + err = NDR_ERR_VALIDATE; + DBG_ERR("failed to extract variant value only for type %s\n", + get_vtype_name(vtype)); + } +out: + return err; +} + +static enum ndr_err_code process_value(TALLOC_CTX *ctx, + DATA_BLOB *rows_buf, + uint32_t nrow_offset, + struct wsp_ctablecolumn *tab_col, + bool is_64bit, + uint32_t cbreserved, + uint64_t client_buf_addr, + struct wsp_cbasestoragevariant *col) +{ + uint64_t client_buf_base_addr = client_buf_addr + cbreserved; + int32_t len = 0; + enum ndr_err_code err = NDR_ERR_SUCCESS; + + uint16_t vtype; + uint8_t *rowbuf_start; + uint32_t pos = 0; + struct value_only_handler *pull_handler = NULL; + + DBG_INFO("\n\tvalueoffset:valuesize 0x%x:0x%x crowvariant address = 0x%x",tab_col->valueoffset.value, + tab_col->valuesize.value, + (tab_col->valueoffset.value + nrow_offset)); + + rowbuf_start = rows_buf->data + nrow_offset; + + pos = tab_col->valueoffset.value; + + if (tab_col->lengthused) { + len = IVAL(rowbuf_start, tab_col->lengthoffset.value); + } + + if (tab_col->vtype != VT_VARIANT) { + pull_handler = get_value_handler(tab_col->vtype & ~VT_VECTOR); + if (!pull_handler) { + /* ignoring, maybe we should error out */ + DBG_ERR("no handler for type %s\n", + get_vtype_name(tab_col->vtype)); + goto out; + } + len -= pos; + err = process_fixed_area_val( + ctx, pull_handler, is_64bit, tab_col->vtype, + len, rowbuf_start, rowbuf_start + pos, + client_buf_base_addr, col); + + } else { + vtype = SVAL(rowbuf_start, pos); + + pos +=2; + pos +=6; /* reserved1 & reserved2 */ + + pull_handler = get_value_handler(vtype & ~VT_VECTOR); + if (!pull_handler) { + /* ignoring, maybe we should error out */ + DBG_ERR("no handler for type %s\n", + get_vtype_name(vtype)); + goto out; + } + if (is_variable_size(vtype)) { + /* for a variable size value (like a string) + * it seems the size is what's at + * lengthoffset - tab_col->valuesize.value + * Note: however this only seems to be true in the + * 32 bit mode case + */ + len = len - tab_col->valuesize.value; + } else { + len = len - (pos - tab_col->valueoffset.value); + } + err = process_variant_val(ctx, pull_handler, is_64bit, vtype, + len, rows_buf->data, rows_buf->length, + rowbuf_start + pos, + client_buf_base_addr, col); + } +out: + return err; +} + +static enum ndr_err_code process_columns(TALLOC_CTX *ctx, + bool is_64bit, + uint32_t cbreserved, + uint64_t client_buf_addr, + struct wsp_cpmsetbindingsin *bindingin, + DATA_BLOB *rows_buf, + uint32_t nrow, + struct wsp_cbasestoragevariant *cols) +{ + int i; + enum ndr_err_code err = NDR_ERR_SUCCESS; + uint32_t nrow_offset = nrow * bindingin->brow; +#if 0 + if (is_64bit) { + DBG_ERR("We don't handle 64 bit mode yet\n"); + err = NDR_ERR_VALIDATE; + goto out; + } +#endif + /* process columns */ + for (i = 0; i < bindingin->ccolumns; i++) { + struct wsp_ctablecolumn *tab_col = &bindingin->acolumns[i]; + uint8_t store_status = 0; /* StoreStatusOk */ + DBG_INFO("\nRow[%d]Col[%d] property %s type %s",nrow, i, + prop_from_fullprop(ctx, &tab_col->propspec), + get_vtype_name(tab_col->vtype)); + if (tab_col->statusused) { + store_status = ((uint8_t)*(rows_buf->data + nrow_offset + tab_col->statusoffset.value)); + DBG_INFO("\n\tstatusoffset 0x%x status is %s", + tab_col->statusoffset.value, + get_store_status(store_status)); + } + if (tab_col->lengthused) { + DBG_INFO("\n\tlengthoffset 0x%x value at length is 0x%x",tab_col->lengthoffset.value, IVAL(rows_buf->data, nrow_offset + tab_col->lengthoffset.value)); + } + if (tab_col->valueused && store_status == 0) { + err = process_value(ctx, rows_buf, nrow_offset, + tab_col, is_64bit, cbreserved, + client_buf_addr, &cols[i]); + if (err) { + goto out; + } + } + } +out: + return err; +} + +enum ndr_err_code extract_rowsarray( + TALLOC_CTX * ctx, + DATA_BLOB *rows_buf, + bool is_64bit, + struct wsp_cpmsetbindingsin *bindingsin, + uint32_t cbreserved, + uint64_t ulclientbase, + uint32_t rows, + struct wsp_cbasestoragevariant **rowsarray) +{ + int i; + enum ndr_err_code err; + + for (i = 0; i < rows; i++ ) { + struct wsp_cbasestoragevariant *cols = + talloc_zero_array(ctx, + struct wsp_cbasestoragevariant, + bindingsin->ccolumns); + err = process_columns(ctx, + is_64bit, + cbreserved, + ulclientbase, + bindingsin, + rows_buf, + i, + cols); + if (err) { + break; + } + rowsarray[i] = cols; + } + return err; +} + +static void process_query_node(TALLOC_CTX *ctx, + struct wsp_crestriction *crestriction, + t_query *node); + +static void process_andornot_node(TALLOC_CTX *ctx, + struct wsp_crestriction *crestr, + t_query *node, + struct wsp_crestriction **left, + struct wsp_crestriction **right) +{ + struct wsp_cnoderestriction *restriction_node; + + *left = NULL; + *right = NULL; + + restriction_node = + &crestr->restriction.cnoderestriction; + + crestr->weight = 1000; + + if (node->type == eAND || node->type == eOR) { + if (node->type == eAND) { + crestr->ultype = RTAND; + } else { + crestr->ultype = RTOR; + } + create_noderestriction(ctx, restriction_node, 2); + *left = &restriction_node->panode[0]; + *right = &restriction_node->panode[1]; + } else { + crestr->ultype = RTNOT; + crestr->restriction.restriction.restriction = + talloc_zero(ctx, struct wsp_crestriction); + crestr= + crestr->restriction.restriction.restriction; + } + if (*left == NULL) { + *left = crestr; + } + if (*right == NULL) { + *right = crestr; + } +} + +static void process_value_node(TALLOC_CTX *ctx, + struct wsp_crestriction *crestriction, + t_query *node) +{ + *crestriction = *node->restriction; +} + +static void process_query_node(TALLOC_CTX *ctx, + struct wsp_crestriction *crestriction, + t_query *node) +{ + struct wsp_crestriction *left = NULL, *right = NULL; + if (node == NULL) { + return; + } + switch (node->type) { + case eAND: + case eOR: + case eNOT: + process_andornot_node(ctx, crestriction, node, + &left, &right); + break; + case eVALUE: + process_value_node(ctx, crestriction, node); + default: + break; + } + process_query_node(ctx, left, node->left); + process_query_node(ctx, right, node->right); +} + +void create_querysearch_request(TALLOC_CTX * ctx, + struct wsp_request* request, + t_select_stmt *sql) +{ + struct wsp_cpmcreatequeryin *createquery = &request->message.cpmcreatequery; + uint32_t indices[sql->cols->num_cols]; + int i; + + for (i = 0; i < sql->cols->num_cols; i++) { + indices[i] = i; + } + + request->header.msg = CPMCREATEQUERY; + createquery->ccolumnsetpresent = 1; + createquery->columnset.columnset.count = sql->cols->num_cols; + fill_uint32_vec(ctx, &createquery->columnset.columnset.indexes, + indices, + sql->cols->num_cols); + + /* handle restrictions */ + createquery->crestrictionpresent = 1; + createquery->restrictionarray.restrictionarray.count = 1; + createquery->restrictionarray.restrictionarray.ispresent = 1; + + create_restriction_array(ctx, + &createquery->restrictionarray.restrictionarray.restrictions, + createquery->restrictionarray.restrictionarray.count); + + process_query_node(ctx, &createquery->restrictionarray.restrictionarray.restrictions[0], sql->where); + + + /* handle rest */ + createquery->csortsetpresent = 1; + if (createquery->csortsetpresent) { + struct wsp_csortset *sortset = &createquery->sortset.sortset; + /* sort on first column */ + struct wsp_csort data[] = { + {0x00000000, 0x00000000, 0x00000000, 0x00001809}, + }; + /* + * not sure if this is important of not, exists in captured + * messages, seems like it is, if we don't have the values below we get an error + */ + sortset->unknown1 = 1; + sortset->unknown2 = 0; + sortset->count = ARRAY_SIZE(data); + fill_sortarray(ctx, &sortset->sortarray, data,sortset->count); + } + + createquery->ccategorizationsetpresent = 0; + + createquery->rowsetproperties.ubooleanoptions = 0x00000203; + createquery->rowsetproperties.ulmaxopenrows = 0x00000000; + createquery->rowsetproperties.ulmemoryusage = 0x00000000; + createquery->rowsetproperties.cmaxresults = 0x00000000; + createquery->rowsetproperties.ccmdtimeout = 0x00000005; + + createquery->pidmapper.count = sql->cols->num_cols; + createquery->pidmapper.apropspec = talloc_zero_array(ctx, + struct wsp_cfullpropspec, + createquery->pidmapper.count); + for(i = 0; i < sql->cols->num_cols; i++) { + struct wsp_cfullpropspec *prop = + &createquery->pidmapper.apropspec[i]; + if (!set_fullpropspec(ctx, + prop, sql->cols->cols[i], + PRSPEC_PROPID)) { + /* #FIXME error handling */ + DBG_ERR("Failed to handle property named %s\n", + sql->cols->cols[i]); + continue; + } + } + createquery->lcid = 0x00001809; +} + +static uint32_t alignval(uint32_t num, int32_t align) { + num = num + (align - (num % align)) % align; + return num; +} + +static int32_t getNextAddress(int32_t value_off, + int32_t status_off, + int32_t len_off, + bool is_64bit) +{ + return MAX(MAX(value_off + get_value_size(is_64bit), status_off + 1), len_off + 2); +} + +static void create_binding_offsets(struct binding *binding, + int no_cols, + bool is_64bit) +{ + uint32_t buf_addr = 0x0; + uint32_t i; + + uint32_t value_off = 0; + uint32_t len_off = 0; + + /* initial state, seems weird but can't handle it any other way */ + uint32_t status_off = 0x1; /* this will get incremented to the desired 0x2 */ + uint32_t avail = 0x4; + int status_remain = 0x2; + int len_remain = -1; + + const static uint32_t WINDOW = 0x8; + const static uint32_t LEN_STAT_SIZE = 0x4; + for (i = 0; i < no_cols; i++) { + buf_addr = buf_addr + WINDOW; + value_off = buf_addr; + + if (status_remain <= 0) { + if (avail) { + status_off = avail; + status_remain = LEN_STAT_SIZE; + avail = 0; + } else { + /* + * we prepare the address to allocate + * another block from here. It will + * be allocated automatically when we + * re-enter the loop */ + status_off = getNextAddress(value_off, + status_off, + len_off, + is_64bit) + WINDOW; + status_remain = LEN_STAT_SIZE; + buf_addr = status_off; + avail = buf_addr + LEN_STAT_SIZE; + } + } else { + status_off++; + buf_addr = getNextAddress(value_off, + status_off, + len_off, + is_64bit); + } + + if (len_remain <= 0) { + if (avail) { + len_off = avail; + len_remain = LEN_STAT_SIZE; + avail = 0; + } else { + /* + * we prepare the address to allocate + * another block from here. It will + * be allocated automatically when we + * re-enter the loop */ + len_off = getNextAddress(value_off, + status_off, + len_off, + is_64bit) + WINDOW; + len_remain = LEN_STAT_SIZE; + buf_addr = len_off; + avail = buf_addr + LEN_STAT_SIZE; + } + } else { + len_off += 0x4; + buf_addr = getNextAddress(value_off, + status_off, + len_off, + is_64bit); + } + status_remain--; + len_remain -= LEN_STAT_SIZE; + binding[i].value_off = value_off; + binding[i].status_off = status_off; + binding[i].len_off = len_off; +#if 0 + printf("Col[%d]\n", i); + printf("\t value offset: 0x%x\n", value_off); + printf("\t status offset: 0x%x remain(%d)\n", status_off, status_remain); + printf("\t length offset: 0x%x remain(%d)\n", len_off, len_remain ); + printf("current buff addr 0x%x\n", buf_addr); +#endif + } +} + +static void fill_bindings(TALLOC_CTX *ctx, + struct wsp_cpmsetbindingsin *bindingsin, + char **col_names, + bool is_64bit) +{ + uint32_t i; + struct binding *offsets; + uint32_t num_cols; + struct wsp_ctablecolumn *tablecols = bindingsin->acolumns; + bindingsin->brow = 0x0; + num_cols = bindingsin->ccolumns; + + offsets = talloc_zero_array(ctx, struct binding, num_cols); + create_binding_offsets(offsets, num_cols, is_64bit); + for (i = 0; i < num_cols; i++) { + uint32_t max_off; + if (!set_ctablecolumn(ctx, &tablecols[i], col_names[i], + &offsets[i], is_64bit)) { + DBG_ERR("Failed to handle property named %s\n", + col_names[i]); + continue; + } + max_off = MAX(offsets[i].value_off + get_value_size(is_64bit), + offsets[i].status_off + 1); + max_off = MAX(max_off, offsets[i].len_off + 2); + if (max_off > bindingsin->brow) { + bindingsin->brow = max_off; + } + } + /* important */ + bindingsin->brow = alignval(bindingsin->brow,4); +} + +void create_setbindings_request(TALLOC_CTX * ctx, + struct wsp_request* request, + bool is_64bit, + t_select_stmt *sql, + uint32_t cursor) +{ + struct wsp_cpmsetbindingsin *bindingsin = &request->message.cpmsetbindings; + request->header.msg = CPMSETBINDINGSIN; + bindingsin->hcursor = cursor; + bindingsin->ccolumns = sql->cols->num_cols; + + bindingsin->acolumns = talloc_zero_array(ctx, struct wsp_ctablecolumn, + bindingsin->ccolumns); + fill_bindings(ctx, bindingsin, sql->cols->cols, is_64bit); + +} + +enum search_kind get_kind(const char* kind_str) +{ + enum search_kind result = Unknown; + int i; + const static struct { + const char* str; + enum search_kind search_kind; + } kind_map[] = { + {"Calendar", Calendar}, + {"Communication", Communication}, + {"Contact", Contact}, + {"Document", Document}, + {"Email", Email}, + {"Feed", Feed}, + {"Folder", Folder}, + {"Game", Game}, + {"InstantMessage", InstantMessage}, + {"Journal", Journal}, + {"Link", Link}, + {"Movie", Movie}, + {"Music", Music}, + {"Note", Note}, + {"Picture", Picture}, + {"Program", Program}, + {"RecordedTV", RecordedTV}, + {"SearchFolder", SearchFolder}, + {"Task", Task}, + {"Video", Video}, + {"WebHistory", WebHistory}, + }; + for (i = 0; i < ARRAY_SIZE(kind_map); i++) { + if (strequal(kind_str, kind_map[i].str)) { + result = kind_map[i].search_kind; + break; + } + } + return result; +} + +struct wsp_client_ctx +{ + struct dcerpc_pipe *p; + struct smbcli_state *cli; + struct smb2_tree *tree; +}; + +static NTSTATUS connect_server_smb(TALLOC_CTX *mem_ctx, + const char *host, + struct tevent_context *ev_ctx, + struct cli_credentials *credentials, + struct smbcli_state **cli) +{ + NTSTATUS status; + struct smbcli_options options; + struct smbcli_session_options session_options; + lpcfg_smbcli_options(cmdline_lp_ctx, &options); + + lpcfg_smbcli_session_options(cmdline_lp_ctx, &session_options); + + status = smbcli_full_connection(mem_ctx, + cli, + host, + lpcfg_smb_ports(cmdline_lp_ctx), + "IPC$", NULL, + lpcfg_socket_options(cmdline_lp_ctx), + credentials, + lpcfg_resolve_context(cmdline_lp_ctx), + ev_ctx, &options, &session_options, + lpcfg_gensec_settings(mem_ctx, + cmdline_lp_ctx)); + return status; +} + +static NTSTATUS connect_server_smb2(TALLOC_CTX *mem_ctx, + const char *host, + struct tevent_context *ev_ctx, + struct cli_credentials *credentials, + struct smb2_tree **tree) +{ + NTSTATUS status; + struct smbcli_options options; + struct smbcli_session_options session_options; + lpcfg_smbcli_options(cmdline_lp_ctx, &options); + + lpcfg_smbcli_session_options(cmdline_lp_ctx, &session_options); + + status = smb2_connect(mem_ctx, + host, + lpcfg_smb_ports(cmdline_lp_ctx), + "IPC$", + lpcfg_resolve_context(cmdline_lp_ctx), + credentials, + tree, + ev_ctx, + &options, + lpcfg_socket_options(cmdline_lp_ctx), + lpcfg_gensec_settings(mem_ctx, + cmdline_lp_ctx) + ); + return status; +} + +static NTSTATUS wait_for_pipe(TALLOC_CTX *mem_ctx, + struct tevent_context *ev_ctx, + bool smb2_or_greater, + struct wsp_client_ctx *ctx, + const char *pipe_name) +{ + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + + if (smb2_or_greater) { + struct smb2_tree *tree = ctx->tree; + req = + smb2cli_wait_pipe_send( + mem_ctx, + ev_ctx, + tree->session->transport->conn, + tree->session->transport->options.request_timeout, + tree->session->smbXcli, + tree->smbXcli, + 0, + pipe_name); + } else { + struct smbcli_state *cli = ctx->cli; + struct smbcli_tree *tree = cli->tree; + /* WHY isn't the tid set already here ? */ + smb1cli_tcon_set_id(tree->smbXcli, tree->tid); + req = smb1cli_wait_named_pipe_send(mem_ctx, ev_ctx, + tree->session->transport->conn, + cli->options.request_timeout, + tree->session->pid, + tree->session->smbXcli, + tree->smbXcli, + pipe_name); + } + if (req == NULL) { + return status; + } + + if (!tevent_req_poll_ntstatus(req, ev_ctx, &status)) { + goto done; + } + + if (smb2_or_greater) { + status = smb2cli_wait_pipe_recv(req); + } else { + status = smb1cli_wait_named_pipe_recv(req); + } +done: + return status; +} + +NTSTATUS wsp_server_connect(TALLOC_CTX *mem_ctx, + const char *servername, + struct tevent_context *ev_ctx, + struct cli_credentials *credentials, + struct wsp_client_ctx **wsp_ctx) +{ + struct wsp_client_ctx *ctx = talloc_zero(mem_ctx, + struct wsp_client_ctx); + struct dcerpc_pipe *p; + struct dcerpc_binding_handle *h; + NTSTATUS status; + bool smb2_or_greater = + (lpcfg_client_max_protocol(cmdline_lp_ctx) >= PROTOCOL_SMB2_02); + if (smb2_or_greater) { + status = connect_server_smb2(mem_ctx, + servername, + ev_ctx, + credentials, + &ctx->tree); + } else { + status = connect_server_smb(mem_ctx, + servername, + ev_ctx, + credentials, + &ctx->cli); + } + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("failed to connect to server status: %s)\n", + nt_errstr(status)); + return status; + } + p = dcerpc_pipe_init(mem_ctx, ev_ctx); + + if (!p) { + DBG_ERR("failed to int the pipe)\n"); + return NT_STATUS_UNSUCCESSFUL; + } + + status = wait_for_pipe(mem_ctx, + ev_ctx, + smb2_or_greater, + ctx, + "MsFteWds"); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("wait for pipe failed: %s)\n", + nt_errstr(status)); + return status; + } + if (smb2_or_greater) { + status = dcerpc_pipe_open_smb2(p, ctx->tree, "MsFteWds"); + } else { + status = dcerpc_pipe_open_smb(p, ctx->cli->tree, "MsFteWds"); + } + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("failed to connect to server status: %s)\n", + nt_errstr(status)); + return status; + } + + h = create_rawpipe_handle(p); + + if (!h) { + DBG_ERR("failed to create the pipe handle)\n"); + return NT_STATUS_UNSUCCESSFUL; + } + + p->binding_handle = h; + ctx->p = p; + *wsp_ctx = ctx; + + return status; +} + +static NTSTATUS write_something(TALLOC_CTX* ctx, + struct dcerpc_pipe *p, + DATA_BLOB *blob_in, + DATA_BLOB *blob_out) +{ + uint32_t outflags; + struct tstream_context *stream; + struct dcerpc_binding_handle *handle = p->binding_handle; + + NTSTATUS status; + + stream = p->conn->transport.stream; + status = tstream_smbXcli_np_use_trans(stream); + + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("failed to set trans mode on pipe status: %s)\n", + nt_errstr(status)); + return status; + } + + /* set large data */ + tstream_smbXcli_np_set_max_data(stream, 42800); + + status = dcerpc_binding_handle_raw_call(handle, + NULL, + 0, + 0, + blob_in->data, + blob_in->length, + ctx, + &blob_out->data, + &blob_out->length, + &outflags); + return status; +} + +static enum ndr_err_code parse_blob(TALLOC_CTX *ctx, DATA_BLOB *blob, + struct wsp_request *request, struct wsp_response *response, + DATA_BLOB *unread) +{ + struct ndr_pull *ndr = NULL; + enum ndr_err_code err; + int ndr_flags = NDR_SCALARS | NDR_BUFFERS; + uint32_t status = 0; + + ndr = ndr_pull_init_blob(blob, ctx); + + /* peek at the status */ + status = IVAL(blob->data, 4); + + /* is hard error ?*/ + if (status & 0x80000000 && blob->length == MSG_HDR_SIZE) { + /* just pull the header */ + err = ndr_pull_wsp_header(ndr, ndr_flags, &response->header); + DBG_ERR("error: %s\n", nt_errstr(NT_STATUS(status))); + goto out; + } + err = ndr_pull_wsp_response(ndr, ndr_flags, response); + if (err) { + DBG_ERR("Failed to pull header from response blob error %d\n", err); + goto out; + } + if (DEBUGLEVEL >=6) { + NDR_PRINT_DEBUG(wsp_response, response); + } + if (response->header.msg == CPMGETROWS) { + if (request) { + /* point to rows buffer */ + ndr->offset = request->message.cpmgetrows.cbreserved; + } + } + + if (ndr->offset < blob->length) { + int bytes = blob->length - ndr->offset; + *unread = data_blob_named(blob->data + ndr->offset, + bytes, "UNREAD"); + DBG_WARNING("\nThere are unprocessed bytes (len 0x%x) at end of message\n", bytes); + } + +out: + return err; +} + +static void set_msg_checksum(DATA_BLOB *blob, struct wsp_header *hdr) +{ + /* point at payload */ + uint32_t i; + uint8_t *buffer = blob->data + MSG_HDR_SIZE; + uint32_t buf_size = blob->length - MSG_HDR_SIZE; + uint32_t nwords = buf_size/4; + uint32_t offset = 0; + uint32_t checksum = 0; + + static const uint32_t xor_const = 0x59533959; + for(i = 0; i < nwords; i++) { + checksum += IVAL(buffer, offset); + offset += 4; + } + + checksum ^= xor_const; + checksum -= hdr->msg; + hdr->checksum = checksum; +} + +static enum ndr_err_code insert_header_and_checksum(TALLOC_CTX *ctx, DATA_BLOB* blob, + struct wsp_request *request) +{ + enum ndr_err_code err; + int ndr_flags = NDR_SCALARS | NDR_BUFFERS; + struct ndr_push *header_ndr = ndr_push_init_ctx(ctx); + + if (request->header.msg == CPMCONNECT + || request->header.msg == CPMCREATEQUERY + || request->header.msg == CPMSETBINDINGSIN + || request->header.msg == CPMGETROWS + || request->header.msg == CPMFETCHVALUE) { + + set_msg_checksum(blob, &request->header); + } + err = ndr_push_wsp_header(header_ndr, ndr_flags, &request->header); + if (err) { + DBG_ERR("Failed to push header, error %d\n", err); + return err; + } + memcpy(blob->data, header_ndr->data, MSG_HDR_SIZE); + return err; +} + +NTSTATUS wsp_request_response(TALLOC_CTX* ctx, + struct wsp_client_ctx *wsp_ctx, + struct wsp_request *request, + struct wsp_response *response, + DATA_BLOB *unread) +{ + struct dcerpc_pipe *p = wsp_ctx->p; + NTSTATUS status = NT_STATUS_OK; + + int ndr_flags = NDR_SCALARS | NDR_BUFFERS; + struct ndr_push* push_ndr; + enum ndr_err_code err; + + DATA_BLOB req_blob; + DATA_BLOB resp_blob; + + ZERO_STRUCT(req_blob); + ZERO_STRUCT(resp_blob); + + push_ndr = ndr_push_init_ctx(ctx); + + /* write message payload first */ + push_ndr->offset = MSG_HDR_SIZE; + DBG_INFO("\n"); + + switch(request->header.msg) { + case CPMCONNECT: + err = ndr_push_wsp_cpmconnectin(push_ndr, ndr_flags, + &request->message.cpmconnect); + break; + case CPMCREATEQUERY: + { + err = ndr_push_wsp_cpmcreatequeryin(push_ndr, ndr_flags, + &request->message.cpmcreatequery); + req_blob = ndr_push_blob(push_ndr); + /* we need to set cpmcreatequery.size */ + request->message.cpmcreatequery.size = req_blob.length - MSG_HDR_SIZE; + SIVAL(req_blob.data, MSG_HDR_SIZE, + request->message.cpmcreatequery.size); + + break; + } + case CPMSETBINDINGSIN: + err = ndr_push_wsp_cpmsetbindingsin(push_ndr, ndr_flags, + &request->message.cpmsetbindings); + req_blob = ndr_push_blob(push_ndr); + /* we need to set cpmsetbindings.bbindingdesc (size) */ + request->message.cpmsetbindings.bbindingdesc = + req_blob.length - MSG_HDR_SIZE - 16; + SIVAL(req_blob.data, MSG_HDR_SIZE + 8, + request->message.cpmsetbindings.bbindingdesc); + break; + case CPMGETROWS: + err = ndr_push_wsp_cpmgetrowsin(push_ndr, ndr_flags, + &request->message.cpmgetrows); + req_blob = ndr_push_blob(push_ndr); + request->message.cpmgetrows.cbseek = req_blob.length - MSG_HDR_SIZE - 32; + /* we need to set cpmgetrowsin.cbseek (size) */ + SIVAL(req_blob.data, MSG_HDR_SIZE + 12, + request->message.cpmgetrows.cbseek); + SIVAL(req_blob.data, MSG_HDR_SIZE + 16, + request->message.cpmgetrows.cbreserved); + break; + case CPMGETQUERYSTATUS: + err = ndr_push_wsp_cpmgetquerystatusin(push_ndr, ndr_flags, + &request->message.cpmgetquerystatus); + break; + case CPMGETQUERYSTATUSEX: + err = ndr_push_wsp_cpmgetquerystatusexin(push_ndr, ndr_flags, + &request->message.cpmgetquerystatusex); + break; + case CPMFREECURSOR: + err = ndr_push_wsp_cpmfreecursorin(push_ndr, ndr_flags, + &request->message.cpmfreecursor); + break; +/* + case CPMFREECURSOR: + status = push_wsp_cpmfreecursorin(buffer, request, + &offset); + break; + case CPMDISCONNECT: + push_wsp_cpmdisconnect(buffer, request, &offset); + break; +*/ + default: + status = NT_STATUS_MESSAGE_NOT_FOUND; + goto out; + break; + } + if (err) { + DBG_ERR("failed to serialise message! (%d)\n", err); + status = NT_STATUS_UNSUCCESSFUL; + goto out; + } + if (!req_blob.data) { + req_blob = ndr_push_blob(push_ndr); + } + err = insert_header_and_checksum(ctx, &req_blob, request); + + DBG_NOTICE("\nsending raw message from client len %d\n", (int)req_blob.length); + DBG_NOTICE("\nsending raw message from client\n"); + DBG_NOTICE( "===============================\n"); + + dump_data(5, req_blob.data, req_blob.length); + + status = write_something(ctx, p, &req_blob, &resp_blob); + + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("Failed to write message\n"); + goto out; + } + DBG_NOTICE("\nraw response from server\n"); + DBG_NOTICE( "========================\n"); + dump_data(5, resp_blob.data, resp_blob.length); + + err = parse_blob(ctx, &resp_blob, request, response, unread); + if (err) { + DBG_ERR("Failed to parse response error %d\n", err); + status = NT_STATUS_UNSUCCESSFUL; + goto out; + } + DBG_NOTICE("response status is 0x%x\n", response->header.status); + /* propagate error status to return status */ + if (response->header.status & 0x80000000) { + status = NT_STATUS_UNSUCCESSFUL; + } +out: + return status; +} + +/* + * tmp accessors, hoping we can remove the need for clients to know about + */ + +struct dcerpc_pipe * get_wsp_pipe(struct wsp_client_ctx *ctx) +{ + return ctx->p; +} + +struct smbcli_state * get_wsp_clistate(struct wsp_client_ctx *ctx) +{ + return ctx->cli; +} diff --git a/source4/libcli/wsp/wsp_cli.h b/source4/libcli/wsp/wsp_cli.h new file mode 100644 index 0000000..496af64 --- /dev/null +++ b/source4/libcli/wsp/wsp_cli.h @@ -0,0 +1,110 @@ +/* + * Unix SMB/CIFS implementation. + * + * Window Search Service + * + * Copyright (c) 2016 Noel Power + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#ifndef __LIBCLI_WSP_WSP_CLI +#define __LIBCLI_WSP_WSP_CLI + +#include "libcli/wsp/wsp_aqs.h" + +enum search_kind { + Calendar, + Communication, + Contact, + Document, + Email, + Feed, + Folder, + Game, + InstantMessage, + Journal, + Link, + Movie, + Music, + Note, + Picture, + Program, + RecordedTV, + SearchFolder, + Task, + Video, + WebHistory, + None, + Unknown, +}; + +enum search_kind get_kind(const char* kind_str); + +void init_connectin_request(TALLOC_CTX *ctx, + struct wsp_request* request, + const char* clientmachine, + const char* clientuser, + const char* server); + +void create_querysearch_request(TALLOC_CTX * ctx, + struct wsp_request* request, + t_select_stmt *sql); + +void create_setbindings_request(TALLOC_CTX * ctx, + struct wsp_request* request, + bool is_64bit, + t_select_stmt *sql, + uint32_t cursor); + +void create_seekat_getrows_request(TALLOC_CTX * ctx, + struct wsp_request* request, + bool is_64bit, + uint32_t cursor, + uint32_t bookmark, + uint32_t skip, + uint32_t rows, + uint32_t cbreserved, + uint64_t client_buf_addr, + uint32_t cbrowwidth, + uint32_t fbwdfetch); + +enum ndr_err_code extract_rowsarray(TALLOC_CTX * ctx, + DATA_BLOB *rows_buf, + bool is_64bit, + struct wsp_cpmsetbindingsin *bindingsin, + uint32_t cbreserved, + uint64_t client_buf_addr, + uint32_t rows, + struct wsp_cbasestoragevariant **rowsarray); + +struct wsp_client_ctx; +struct cli_credentials; + +NTSTATUS wsp_server_connect(TALLOC_CTX *mem_ctx, + const char *servername, + struct tevent_context *ev_ctx, + struct cli_credentials *credential, + struct wsp_client_ctx **ctx); + +/* simple sync api */ +NTSTATUS wsp_request_response(TALLOC_CTX* ctx, + struct wsp_client_ctx *wsp_ctx, + struct wsp_request *request, + struct wsp_response *response, + DATA_BLOB *unread); + +/* tmp accessors */ +struct dcerpc_pipe * get_wsp_pipe(struct wsp_client_ctx *ctx); +struct smbcli_state * get_wsp_clistate(struct wsp_client_ctx *ctx); +#endif -- 2.10.2 >From e271ad22b5965b802dcd38e47a9e90617b6fc739 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Thu, 21 Jul 2016 16:53:17 +0100 Subject: [PATCH 10/10] s4/utils: Add search client Simple cli client for doing a basic windows search. example: wspsearch -U$(USER)%$(PASSWD) //$(SERVER)/$(SHARE) --search='DSC' --kind=Picture Signed-off-by: Noel Power --- source4/utils/wscript_build | 6 + source4/utils/wspsearch.c | 732 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 738 insertions(+) create mode 100644 source4/utils/wspsearch.c diff --git a/source4/utils/wscript_build b/source4/utils/wscript_build index 046e237..193864c 100644 --- a/source4/utils/wscript_build +++ b/source4/utils/wscript_build @@ -17,3 +17,9 @@ bld.SAMBA_BINARY('oLschema2ldif', deps='samdb POPT_SAMBA' ) +bld.SAMBA_BINARY('wspsearch', + source='wspsearch.c', + deps='popt POPT_SAMBA POPT_CREDENTIALS dcerpc LIBSAMBA_WSP LIBCLI_SMB SMBREADLINE NDR_WSP NDR_WSP_DATA ', + enabled=bld.env.with_wsp + ) + diff --git a/source4/utils/wspsearch.c b/source4/utils/wspsearch.c new file mode 100644 index 0000000..ee0617d --- /dev/null +++ b/source4/utils/wspsearch.c @@ -0,0 +1,732 @@ +/* + * Unix SMB/CIFS implementation. + * + * Window Search Service + * + * Copyright (c) 2016 Noel Power + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#include "includes.h" +#include "bin/default/librpc/gen_ndr/ndr_wsp.h" +#include "bin/default/librpc/gen_ndr/ndr_wsp_data.h" +#include "librpc/rpc/wsp_helper.h" +#include "libcli/wsp/wsp_cli.h" +#include "lib/cmdline/popt_common.h" +#include "lib/events/events.h" +#include "auth/gensec/gensec.h" +#include "util/tevent_ntstatus.h" +#include "util/debug.h" +#include "dcerpc.h" +#include "credentials.h" +#include "param/param.h" +#include "libcli/wsp/wsp_aqs.h" + +#define CLIENT_BUF_ADDR 0xDEAbd860 + +#if DEVELOPER +static bool is_operator_node(t_query *node) +{ + if (node->type == eVALUE) { + return false; + } + return true; +} + +static const char *nodetype_as_string(t_nodetype node) +{ + const char *result = NULL; + switch (node) { + case eNOT: + result = "NOT"; + break; + case eAND: + result = "AND"; + break; + case eOR: + result = "OR"; + break; + case eVALUE: + default: + break; + } + return result; +} + +static const char *restriction_as_string(TALLOC_CTX *ctx, + struct wsp_crestriction *crestriction ) +{ + const char *result = NULL; + if (crestriction->ultype == RTPROPERTY) { + struct wsp_cpropertyrestriction *prop_restr = + &crestriction->restriction.cpropertyrestriction; + struct wsp_cbasestoragevariant *value = &prop_restr->prval; + result = variant_as_string(ctx, value, true); + } else { + struct wsp_ccontentrestriction *cont_restr = NULL; + cont_restr = &crestriction->restriction.ccontentrestriction; + result = talloc_strdup(ctx, cont_restr->pwcsphrase); + } + return result; +} + +static const char* prop_name_from_restriction( + TALLOC_CTX *ctx, + struct wsp_crestriction *restriction) +{ + const char* result; + struct wsp_cfullpropspec *prop; + if (restriction->ultype == RTCONTENT) { + prop = &restriction->restriction.ccontentrestriction.property; + } else { + prop = &restriction->restriction.cpropertyrestriction.property; + } + result = prop_from_fullprop(ctx, prop); + return result; +} + +static void print_basic_query(struct wsp_crestriction *restriction) +{ + TALLOC_CTX *ctx = talloc_init("print_basic_query"); + const char *op_str = op_as_string(restriction); + const char *val_str = restriction_as_string(ctx, restriction); + const char *prop_name = prop_name_from_restriction(ctx, restriction); + printf("%s %s %s", prop_name, op_str ? op_str : "", val_str); + TALLOC_FREE(ctx); +} + +static void print_node(t_query *node, bool is_rpn) +{ + switch(node->type) { + case eAND: + case eOR: + case eNOT: + printf(" %s ", nodetype_as_string(node->type)); + break; + case eVALUE: + default: + print_basic_query(node->restriction); + break; + } +} + +/* + * Algorithm infix (tree) + * Print the infix expression for an expression tree. + * Pre : tree is a pointer to an expression tree + * Post: the infix expression has been printed + * if (tree not empty) + * if (tree token is operator) + * print (open parenthesis) + * end if + * infix (tree left subtree) + * print (tree token) + * infix (tree right subtree) + * if (tree token is operator) + * print (close parenthesis) + * end if + * end if + *end infix + */ + +static void infix(t_query *tree) +{ + if (tree == NULL) { + return; + } + if (is_operator_node(tree)) { + printf("("); + } + infix(tree->left); + print_node(tree, false); + infix(tree->right); + if (is_operator_node(tree)) { + printf(")"); + } +} + +static void dump_cols(t_select_stmt *select) +{ + t_col_list *cols = select->cols; + if (cols) { + int i; + for (i = 0; i < cols->num_cols; i++) { + if (i == 0) { + printf("%s", cols->cols[i]); + } else { + printf(", %s", cols->cols[i]); + } + } + } +} + +static void dump_sql(t_select_stmt *select) +{ + if (!select) { + return; + } + printf("selecting the following columns\n"); + dump_cols(select); + printf("\n"); + printf("parsed query:\n"); + infix(select->where); + printf("\n"); +} + +static int test_query(TALLOC_CTX *ctx, t_select_stmt *select) +{ + struct wsp_request request; + struct wsp_crestrictionarray *restrictionset = NULL; + const char *restrictionset_expr = NULL; + NTSTATUS status; + ZERO_STRUCT(request); + dump_sql(select); + create_querysearch_request(ctx, &request, select); + + restrictionset = + &request.message.cpmcreatequery.restrictionarray.restrictionarray; + + restrictionset_expr = + raw_restriction_to_string(ctx, + &restrictionset->restrictions[0]); + if (restrictionset_expr == NULL) { + status = NT_STATUS_UNSUCCESSFUL; + } else { + status = NT_STATUS_OK; + } + if (NT_STATUS_IS_OK(status)) { + printf("restriction expression =>%s<=\n", restrictionset_expr); + } else { + printf("error status %s\n", + nt_errstr(status)); + } + return 0; +} +#endif + +/* send connectin message */ +static NTSTATUS connect(TALLOC_CTX *ctx, + struct wsp_client_ctx *wsp_ctx, + const char* clientmachine, + const char* clientuser, + const char* server, + bool *is_64bit) +{ + struct wsp_request *request; + struct wsp_response *response; + uint32_t client_ver; + uint32_t server_ver; + DATA_BLOB unread; + NTSTATUS status; + TALLOC_CTX *local_ctx = talloc_new(ctx); + + ZERO_STRUCT(unread); + + request = talloc_zero(local_ctx, struct wsp_request); + response = talloc_zero(local_ctx, struct wsp_response); + + init_connectin_request(local_ctx, request, + clientmachine, clientuser, server); + + status = wsp_request_response(local_ctx, wsp_ctx, request, response, &unread); + if (NT_STATUS_IS_OK(status)) { + client_ver = request->message.cpmconnect.iclientversion; + server_ver = response->message.cpmconnect.server_version; + *is_64bit = (server_ver & 0xffff0000) && (client_ver & 0xffff0000); + } + data_blob_free(&unread); + TALLOC_FREE(local_ctx); + return status; +} + +static NTSTATUS create_query(TALLOC_CTX *ctx, + struct wsp_client_ctx *wsp_ctx, + t_select_stmt *select, + uint32_t *single_cursor) +{ + struct wsp_request *request; + struct wsp_response *response; + NTSTATUS status; + DATA_BLOB unread; + TALLOC_CTX *local_ctx = talloc_new(ctx); + + ZERO_STRUCT(unread); + request = talloc_zero(local_ctx, struct wsp_request); + response = talloc_zero(local_ctx, struct wsp_response); + + create_querysearch_request(ctx, request, select); + status = wsp_request_response(local_ctx, wsp_ctx, request, response, &unread); + if (NT_STATUS_IS_OK(status)) { + if (unread.length == 4) { + *single_cursor = IVAL(unread.data, 0); + } + } + data_blob_free(&unread); + TALLOC_FREE(local_ctx); + return status; +} + +static NTSTATUS create_bindings(TALLOC_CTX *ctx, + struct wsp_client_ctx *wsp_ctx, + bool is_64bit, + t_select_stmt *select, + uint32_t cursor, + struct wsp_cpmsetbindingsin *bindings_out) +{ + struct wsp_request *request; + struct wsp_response *response; + NTSTATUS status; + DATA_BLOB unread; + + ZERO_STRUCT(unread); + + request = talloc_zero(ctx, struct wsp_request); + response = talloc_zero(ctx, struct wsp_response); + create_setbindings_request(ctx, request, is_64bit, select, cursor); + status = wsp_request_response(ctx, wsp_ctx, request, response, &unread); + if (NT_STATUS_IS_OK(status)) { + *bindings_out = request->message.cpmsetbindings; + } + data_blob_free(&unread); + return status; +} + +static NTSTATUS create_querystatusex(TALLOC_CTX *ctx, + struct wsp_client_ctx *wsp_ctx, + uint32_t cursor, + uint32_t *nrows) +{ + struct wsp_request *request; + struct wsp_response *response; + NTSTATUS status; + DATA_BLOB unread; + TALLOC_CTX *local_ctx = talloc_new(ctx); + + ZERO_STRUCT(unread); + + request = talloc_zero(local_ctx, struct wsp_request); + response = talloc_zero(local_ctx, struct wsp_response); + request->header.msg = CPMGETQUERYSTATUSEX; + request->message.cpmgetquerystatusex.hcursor = cursor; + request->message.cpmgetquerystatusex.bmk = 0xfffffffc; + status = wsp_request_response(local_ctx, wsp_ctx, request, response, &unread); + if (NT_STATUS_IS_OK(status)) { + *nrows = response->message.cpmgetquerystatusex.resultsfound;; + } + data_blob_free(&unread); + TALLOC_FREE(local_ctx); + return status; +} + + + +static NTSTATUS print_rowsreturned( + TALLOC_CTX *ctx, + DATA_BLOB *buffer, + bool is_64bit, + bool disp_all_cols, + struct wsp_cpmsetbindingsin *bindings, + uint32_t cbreserved, + uint64_t address, + uint32_t rowsreturned, + uint32_t *rows_processed) +{ + NTSTATUS status; + int row = 0; + TALLOC_CTX *local_ctx = talloc_init("results"); + struct wsp_cbasestoragevariant **rowsarray = + talloc_zero_array(local_ctx, + struct wsp_cbasestoragevariant*, + rowsreturned); + + enum ndr_err_code err = extract_rowsarray(rowsarray, + buffer, + is_64bit, + bindings, + cbreserved, + address, + rowsreturned, + rowsarray); + + if (err) { + DBG_ERR("failed to extract rows from getrows response\n"); + status = NT_STATUS_UNSUCCESSFUL; + goto out; + } + + for(; row < rowsreturned; row++) { + TALLOC_CTX *row_ctx = talloc_init("row"); + const char *col_str = NULL; + if (disp_all_cols) { + int i; + for (i = 0; i < bindings->ccolumns; i++){ + col_str = + variant_as_string( + row_ctx, + &rowsarray[row][i], + true); + if (col_str) { + printf("%s%s", + i ? ", " : "", col_str); + } else { + printf("%sN/A", + i ? ", " : ""); + } + } + } else { + col_str = variant_as_string( + row_ctx, + &rowsarray[row][0], + true); + printf("%s", col_str); + } + printf("\n"); + TALLOC_FREE(row_ctx); + } + TALLOC_FREE(local_ctx); + status = NT_STATUS_OK; +out: + *rows_processed = row; + return status; +} + +static NTSTATUS create_getrows(TALLOC_CTX *ctx, + struct wsp_client_ctx *wsp_ctx, + struct wsp_cpmsetbindingsin *bindings, + uint32_t cursor, + uint32_t nrows, + bool disp_all_cols, + bool is_64bit) +{ + struct wsp_request *request; + struct wsp_response *response; + NTSTATUS status; + DATA_BLOB unread; + uint32_t bmk = 0; + uint32_t skip = 0; + uint32_t requested_rows = 0; + uint32_t total_rows = 0; + uint32_t INITIAL_ROWS = 32; + uint32_t rows_printed; + uint32_t current_row = 0; + TALLOC_CTX *row_ctx; + ZERO_STRUCT(unread); + + while (total_rows != nrows) { + row_ctx = talloc_new(ctx); + if (!row_ctx) { + status = NT_STATUS_UNSUCCESSFUL; + goto out; + } + request = talloc_zero(row_ctx, struct wsp_request); + response = talloc_zero(request, struct wsp_response); + if (requested_rows == 0) { + uint32_t remaining_rows = nrows - total_rows; + if ( remaining_rows < INITIAL_ROWS) { + requested_rows = remaining_rows; + } else { + requested_rows = INITIAL_ROWS; + } + bmk = 0xfffffffc; + skip = total_rows; + } + + create_seekat_getrows_request(request, + request, + is_64bit, + cursor, + bmk, + skip, + requested_rows, + 40, + CLIENT_BUF_ADDR, + bindings->brow, + 0); + + status = wsp_request_response(request, wsp_ctx, request, response, &unread); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + total_rows += response->message.cpmgetrows.rowsreturned; + if (response->message.cpmgetrows.rowsreturned + != requested_rows) { + if (response->message.cpmgetrows.etype == EROWSEEKAT) { + struct wsp_cpmgetrowsout *resp; + struct wsp_crowseekat *seekat; + resp = &response->message.cpmgetrows; + seekat = + &resp->seekdescription.crowseekat; + bmk = seekat->bmkoffset; + skip = seekat->cskip; + requested_rows = + requested_rows - response->message.cpmgetrows.rowsreturned; + } + } else { + requested_rows = 0; + } + status = print_rowsreturned(request, &unread, + is_64bit, + disp_all_cols, + bindings, 40, + CLIENT_BUF_ADDR, + response->message.cpmgetrows.rowsreturned, + &rows_printed); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + current_row += rows_printed; + data_blob_free(&unread); + TALLOC_FREE(row_ctx); + } +out: + TALLOC_FREE(row_ctx); + return status; +} + + +const char *default_column = "System.ItemUrl"; + +static char * build_default_sql(TALLOC_CTX *ctx, + const char *kind, + const char *phrase, + const char *location) +{ + char *sql = NULL; + + sql = talloc_asprintf(ctx, + "Scope:\"%s\" AND NOT System.Shell.SFGAOFlagsStrings:hidden" + " AND NOT System.Shell.OmitFromView:true", location); + + if (kind) { + sql = talloc_asprintf(ctx, "System.Kind:%s AND %s", + kind, sql); + } + + if (phrase) { + sql = talloc_asprintf(ctx, + "All:$=\"%s\" OR All:$<\"%s\"" + " AND %s", phrase, phrase, sql); + } + sql = talloc_asprintf(ctx, "SELECT %s" + " WHERE %s", default_column, sql); + return sql; +} + +int main(int argc, const char *argv[]) +{ + int opt; + int result = 0; + NTSTATUS status = NT_STATUS_OK; + poptContext pc; + char* server = NULL; + char* share = NULL; + char* path = NULL; + char* location = NULL; + char* query = NULL; + bool custom_query = false; + const char* phrase = NULL; + const char* kind = NULL; + uint32_t limit = 500; + uint32_t nrows = 0; + struct wsp_cpmsetbindingsin bindings_used; + bool is_64bit = false; + struct poptOption long_options[] = { + POPT_AUTOHELP + { "limit", 0, POPT_ARG_INT, &limit, 0, "limit results", "default is 500, specifying 0 means unlimited" }, + { "search", 0, POPT_ARG_STRING, &phrase, 0, "Search phrase", "phrase" }, + { "kind", 0, POPT_ARG_STRING, &kind, 0, "Kind of thing to search for [Calendar|Communication|Contact|Document|Email|Feed|Folder|Game|InstantMessage|Journal|Link|Movie|Music|Note|Picture|Program|RecordedTV|SearchFolder|Task|Video|WebHistory]", "kind" }, + { "query", 0, POPT_ARG_STRING, &query, 0, "specify a more complex query", "query" }, + POPT_COMMON_SAMBA + POPT_COMMON_CONNECTION + POPT_COMMON_CREDENTIALS + POPT_TABLEEND + }; + TALLOC_CTX *frame = talloc_stackframe(); + struct tevent_context *ev_ctx + = s4_event_context_init(talloc_tos()); + struct dcerpc_pipe *p; + uint32_t cursor; + struct wsp_client_ctx *wsp_ctx; + t_select_stmt *select_stmt; + + gensec_init(); + + pc = poptGetContext("wspsearch", argc, argv, long_options, 0); + poptSetOtherOptionHelp(pc, "//server1/share1"); + + while ((opt = poptGetNextOpt(pc)) != -1) ; + + if(!poptPeekArg(pc)) { + poptPrintUsage(pc, stderr, 0); + result = -1; + goto out; + } + + path = talloc_strdup(talloc_tos(), poptGetArg(pc)); + if (!path || limit < 0) { + DBG_ERR("Invalid argument\n"); + result = -1; + goto out; + } + + string_replace(path,'/','\\'); + server = talloc_strdup(talloc_tos(), path+2); + if (!server) { + DBG_ERR("Invalid argument\n"); + return -1; + } + + if (server) { + /* + * if we specify --query then we don't need actually need the + * share part, if it is specified then we don't care as we + * expect the scope to be part of the query (and if it isn't + * then it will probably fail anyway) + */ + share = strchr_m(server,'\\'); + if (!query && !share) { + DBG_ERR("Invalid argument\n"); + return -1; + } + if (share) { + *share = 0; + share++; + } + } + + + DBG_INFO("server name is %s\n", server ? server : "N/A"); + DBG_INFO("share name is %s\n", share ? share : "N/A"); + DBG_INFO("search phrase is %s\n", phrase ? phrase : "N/A"); + DBG_INFO("search kind is %s\n", kind ? kind : "N/A"); + + if (!query && (kind == NULL && phrase == NULL)) { + poptPrintUsage(pc, stderr, 0); + result = -1; + goto out; + } + + if (!query) { + location = talloc_asprintf(talloc_tos(), + "FILE://%s/%s", server, share); + query = build_default_sql(talloc_tos(), kind, phrase, location); + if (!query) { + result = -1; + goto out; + } + } else { + custom_query = true; + } + + select_stmt = get_wsp_sql_tree(query); + + poptFreeContext(pc); + + if (select_stmt == NULL) { + printf("query failed\n"); + result = -1; + goto out; + } + + if (select_stmt->cols == NULL) { + select_stmt->cols = talloc_zero(select_stmt, t_col_list); + select_stmt->cols->num_cols = 1; + select_stmt->cols->cols = + talloc_zero_array(select_stmt->cols, char*, 1); + select_stmt->cols->cols[0] = + talloc_strdup(select_stmt->cols, default_column); + } + +#if DEVELOPER + if (query) { + result = test_query(talloc_tos(), select_stmt); + } +#endif + status = wsp_server_connect(talloc_tos(), + server, + ev_ctx, + cmdline_credentials, + &wsp_ctx); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("failed to connect to wsp service status: %s\n", + nt_errstr(status)); + result = -1; + goto out; + } + + p = get_wsp_pipe(wsp_ctx); + dcerpc_binding_handle_set_timeout(p->binding_handle, + DCERPC_REQUEST_TIMEOUT * 1000); + + /* connect */ + DBG_INFO("sending connect\n"); + status = connect(talloc_tos(), + wsp_ctx, + lpcfg_netbios_name(cmdline_lp_ctx), + cli_credentials_get_username(cmdline_credentials), + server, + &is_64bit); + + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("failed to connect to wsp: %s\n", + nt_errstr(status)); + result = -1; + goto out; + } + + DBG_INFO("sending query\n"); + + status = create_query(talloc_tos(), wsp_ctx, select_stmt, &cursor); + + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("failed to send query: %s)\n", + nt_errstr(status)); + result = -1; + goto out; + } + + DBG_INFO("sending createbindings\n"); + /* set bindings */ + status = create_bindings(talloc_tos(), wsp_ctx, is_64bit, select_stmt, cursor, &bindings_used); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("failed to setbindings: %s)\n", + nt_errstr(status)); + result = -1; + goto out; + } + + status = create_querystatusex(talloc_tos(), + wsp_ctx, + bindings_used.hcursor, + &nrows); + if (!nrows) { + result = 0; + printf("no results found\n"); + goto out; + } + + printf("found %d results, returning %d \n", nrows, limit ? MIN(nrows, limit) : nrows); + status = create_getrows(talloc_tos(), + wsp_ctx, + &bindings_used, + bindings_used.hcursor, + limit ? MIN(nrows, limit) : nrows, + custom_query, + is_64bit); + result = 0; +out: + TALLOC_FREE(frame); + return result; +} -- 2.10.2