+#include "smb.h"
+
+/* Global hf index fields */
+
+static int hf_rc = -1;
+static int hf_hnd = -1;
+static int hf_access_mask = -1;
+
+/* OpenHKLM */
+
+static int hf_openhklm_unknown1 = -1;
+static int hf_openhklm_unknown2 = -1;
+
+/* QueryKey */
+
+static int hf_querykey_class = -1;
+static int hf_querykey_num_subkeys = -1;
+static int hf_querykey_max_subkey_len = -1;
+static int hf_querykey_reserved = -1;
+static int hf_querykey_num_values = -1;
+static int hf_querykey_max_valname_len = -1;
+static int hf_querykey_max_valbuf_size = -1;
+static int hf_querykey_secdesc = -1;
+
+/* Data that is passed to a open call */
+
+static int
+dissect_open_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ offset = dissect_ndr_uint16(
+ tvb, offset, pinfo, tree, drep,
+ hf_openhklm_unknown1, NULL);
+
+ offset = dissect_ndr_uint16(
+ tvb, offset, pinfo, tree, drep,
+ hf_openhklm_unknown1, NULL);
+
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, tree, drep,
+ hf_access_mask, NULL);
+
+ return offset;
+}
+
+/*
+ * OpenHKLM
+ */
+
+static int
+RegOpenHKLM_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+
+ if (dcv->rep_frame != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "Reply in frame %u", dcv->rep_frame);
+
+ /* Parse packet */
+
+ offset = dissect_ndr_pointer(
+ tvb, offset, pinfo, tree, drep,
+ dissect_open_data,
+ NDR_POINTER_UNIQUE, "Unknown", -1, 0);
+
+ dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+static int
+RegOpenHKLM_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+ e_ctx_hnd policy_hnd;
+
+ if (dcv->req_frame != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "Request in frame %u", dcv->req_frame);
+
+ /* Parse packet */
+
+ offset = dissect_nt_policy_hnd(
+ tvb, offset, pinfo, tree, drep,
+ hf_hnd, &policy_hnd, TRUE, FALSE);
+
+ dcerpc_smb_store_pol_name(&policy_hnd, "HKLM handle");
+
+ offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
+ hf_rc, NULL);
+
+ dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+/*
+ * OpenHKU
+ */
+
+static int
+RegOpenHKU_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+
+ if (dcv->rep_frame != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "Reply in frame %u", dcv->rep_frame);
+
+ /* Parse packet */
+
+ offset = dissect_ndr_pointer(
+ tvb, offset, pinfo, tree, drep,
+ dissect_open_data,
+ NDR_POINTER_UNIQUE, "Unknown", -1, 0);
+
+ dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+static int
+RegOpenHKU_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+ e_ctx_hnd policy_hnd;
+
+ if (dcv->req_frame != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "Request in frame %u", dcv->req_frame);
+
+ /* Parse packet */
+
+ offset = dissect_nt_policy_hnd(
+ tvb, offset, pinfo, tree, drep,
+ hf_hnd, &policy_hnd, TRUE, FALSE);
+
+ dcerpc_smb_store_pol_name(&policy_hnd, "HKU handle");
+
+ offset = dissect_ntstatus(
+ tvb, offset, pinfo, tree, drep, hf_rc, NULL);
+
+ dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+/*
+ * OpenHKCR
+ */
+
+static int
+RegOpenHKCR_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+
+ if (dcv->rep_frame != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "Reply in frame %u", dcv->rep_frame);
+
+ /* Parse packet */
+
+ offset = dissect_ndr_pointer(
+ tvb, offset, pinfo, tree, drep,
+ dissect_open_data,
+ NDR_POINTER_UNIQUE, "Unknown", -1, 0);
+
+ dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+static int
+RegOpenHKCR_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+ e_ctx_hnd policy_hnd;
+
+ if (dcv->req_frame != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "Request in frame %u", dcv->req_frame);
+
+ /* Parse packet */
+
+ offset = dissect_nt_policy_hnd(
+ tvb, offset, pinfo, tree, drep,
+ hf_hnd, &policy_hnd, TRUE, FALSE);
+
+ dcerpc_smb_store_pol_name(&policy_hnd, "HKCR handle");
+
+ offset = dissect_ntstatus(
+ tvb, offset, pinfo, tree, drep, hf_rc, NULL);
+
+ dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+/*
+ * RegClose
+ */
+
+static int
+RegClose_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+
+ if (dcv->rep_frame != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "Reply in frame %u", dcv->rep_frame);
+
+ /* Parse packet */
+
+ offset = dissect_nt_policy_hnd(
+ tvb, offset, pinfo, tree, drep,
+ hf_hnd, NULL, FALSE, TRUE);
+
+ dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+static int
+RegClose_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+
+ if (dcv->req_frame != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "Request in frame %u", dcv->req_frame);
+
+ /* Parse packet */
+
+ offset = dissect_nt_policy_hnd(
+ tvb, offset, pinfo, tree, drep,
+ hf_hnd, NULL, FALSE, FALSE);
+
+ offset = dissect_ntstatus(
+ tvb, offset, pinfo, tree, drep, hf_rc, NULL);
+
+ dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+/*
+ * RegQueryKey
+ */
+
+static int
+RegQueryKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+
+ if (dcv->rep_frame != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "Reply in frame %u", dcv->rep_frame);
+
+ /* Parse packet */
+
+ offset = dissect_nt_policy_hnd(
+ tvb, offset, pinfo, tree, drep,
+ hf_hnd, NULL, FALSE, FALSE);
+
+ offset = dissect_ndr_nt_UNICODE_STRING(
+ tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
+
+ dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+static int
+RegQueryKey_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+
+ if (dcv->req_frame != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "Request in frame %u", dcv->req_frame);
+
+ /* Parse packet */
+
+ offset = dissect_ndr_nt_UNICODE_STRING(
+ tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
+
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, tree, drep,
+ hf_querykey_num_subkeys, NULL);
+
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, tree, drep,
+ hf_querykey_max_subkey_len, NULL);
+
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, tree, drep,
+ hf_querykey_reserved, NULL);
+
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, tree, drep,
+ hf_querykey_num_values, NULL);
+
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, tree, drep,
+ hf_querykey_max_valname_len, NULL);
+
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, tree, drep,
+ hf_querykey_max_valbuf_size, NULL);
+
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, tree, drep,
+ hf_querykey_secdesc, NULL);
+
+ /* FIXME: do time properly */
+
+ proto_tree_add_text(tree, tvb, offset, 8, "Mod time");
+ offset += 8;
+
+ offset = dissect_ntstatus(
+ tvb, offset, pinfo, tree, drep, hf_rc, NULL);
+
+ dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+#if 0
+
+/* Templates for new subdissectors */
+
+/*
+ * FOO
+ */
+
+static int
+RegFoo_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+
+ if (dcv->rep_frame != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "Reply in frame %u", dcv->rep_frame);
+
+ /* Parse packet */
+
+ dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+static int
+RegFoo_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
+{
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+
+ if (dcv->req_frame != 0)
+ proto_tree_add_text(tree, tvb, offset, 0,
+ "Request in frame %u", dcv->req_frame);
+
+ /* Parse packet */
+
+ offset = dissect_ntstatus(
+ tvb, offset, pinfo, tree, drep, hf_rc, NULL);
+
+ dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+
+ return offset;
+}
+
+#endif