From Martin Regner: fix dissection of non-standard parameters.
[obnox/wireshark/wip.git] / packet-dcerpc-reg.c
index 4642fb7c2d3d8179ba215c10362d479f9ba67175..f986fd0c6e14ac6f667ff7d8f87f8d4a4c18d336 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for SMB \PIPE\winreg packet disassembly
  * Copyright 2001-2003 Tim Potter <tpot@samba.org>
  *
- * $Id: packet-dcerpc-reg.c,v 1.16 2003/04/21 01:13:41 guy Exp $
+ * $Id: packet-dcerpc-reg.c,v 1.21 2003/08/04 02:49:02 tpot Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
 static int hf_rc = -1;
 static int hf_hnd = -1;
 static int hf_access_mask = -1;
+static int hf_keytype = -1;
+static int hf_keydata = -1;
+static int hf_offered = -1;
+static int hf_returned = -1;
+static int hf_reserved = -1;
+static int hf_unknown = -1;
 
 /* OpenHKLM */
 
@@ -102,8 +108,6 @@ RegOpenHKLM_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
                dissect_open_data,
                NDR_POINTER_UNIQUE, "Unknown", -1);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
-
        return offset;
 }
 
@@ -112,19 +116,23 @@ RegOpenHKLM_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
              proto_tree *tree, char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
 
        /* 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");
+               hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
 
        offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
-                                 hf_rc, NULL);
+                                 hf_rc, &status);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+       if (status == 0) {
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKLM handle");
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": HKLM handle");
+       }
 
        return offset;
 }
@@ -144,8 +152,6 @@ RegOpenHKU_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
                dissect_open_data,
                NDR_POINTER_UNIQUE, "Unknown", -1);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
-
        return offset;
 }
 
@@ -154,19 +160,23 @@ RegOpenHKU_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
             proto_tree *tree, char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
 
        /* 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");
+               hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
 
        offset = dissect_ntstatus(
-               tvb, offset, pinfo, tree, drep, hf_rc, NULL);
+               tvb, offset, pinfo, tree, drep, hf_rc, &status);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+       if (status == 0) {
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKU handle");
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": HKU handle");
+       }
 
        return offset;
 }
@@ -186,8 +196,6 @@ RegOpenHKCR_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
                dissect_open_data,
                NDR_POINTER_UNIQUE, "Unknown", -1);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
-
        return offset;
 }
 
@@ -196,19 +204,23 @@ RegOpenHKCR_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
              proto_tree *tree, char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
 
        /* 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");
+               hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
 
        offset = dissect_ntstatus(
-               tvb, offset, pinfo, tree, drep, hf_rc, NULL);
+               tvb, offset, pinfo, tree, drep, hf_rc, &status);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+       if (status == 0) {
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKCR handle");
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": HKCR handle");
+       }
 
        return offset;
 }
@@ -225,9 +237,7 @@ RegClose_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, TRUE);
-
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+               hf_hnd, NULL, NULL, FALSE, TRUE);
 
        return offset;
 }
@@ -240,13 +250,11 @@ RegClose_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, FALSE);
+               hf_hnd, NULL, 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;
 }
 
@@ -262,13 +270,11 @@ RegQueryKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, FALSE);
+               hf_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_counted_string(
                tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
-
        return offset;
 }
 
@@ -315,8 +321,6 @@ RegQueryKey_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_rc, NULL);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
-
        return offset;
 }
 
@@ -332,7 +336,7 @@ RegOpenEntry_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, FALSE);
+               hf_hnd, NULL, NULL, FALSE, FALSE);
 
        offset = dissect_ndr_counted_string(
                tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
@@ -345,8 +349,6 @@ RegOpenEntry_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
                tvb, offset, pinfo, tree, drep,
                hf_access_mask, NULL);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
-
        return offset;
 }
 
@@ -355,19 +357,24 @@ RegOpenEntry_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
               proto_tree *tree, char *drep)
 {
        e_ctx_hnd policy_hnd;
+       proto_item *hnd_item;
+       guint32 status;
 
        /* 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, "OpenEntry handle");
+               hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
 
        offset = dissect_ntstatus(
-               tvb, offset, pinfo, tree, drep, hf_rc, NULL);
+               tvb, offset, pinfo, tree, drep, hf_rc, &status);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+       if (status == 0) {
+               dcerpc_smb_store_pol_name(&policy_hnd, pinfo,
+                       "OpenEntry handle");
+               if (hnd_item != NULL)
+                       proto_item_append_text(hnd_item, ": OpenEntry handle");
+       }
 
        return offset;
 }
@@ -384,9 +391,7 @@ RegUnknown1A_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, FALSE);
-
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+               hf_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -404,8 +409,6 @@ RegUnknown1A_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_rc, NULL);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
-
        return offset;
 }
 
@@ -421,9 +424,7 @@ RegEnumKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        offset = dissect_nt_policy_hnd(
                tvb, offset, pinfo, tree, drep,
-               hf_hnd, NULL, FALSE, FALSE);
-
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+               hf_hnd, NULL, NULL, FALSE, FALSE);
 
        return offset;
 }
@@ -437,7 +438,137 @@ RegEnumKey_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_rc, NULL);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
+       return offset;
+}
+
+/*
+ * RegQueryValue
+ */
+
+static int
+dissect_reserved(tvbuff_t *tvb, int offset, packet_info *pinfo,
+                proto_tree *tree, char *drep)
+{
+       offset = dissect_ndr_uint32(
+               tvb, offset, pinfo, tree, drep, hf_reserved, NULL);
+
+       return offset;
+}
+
+static int
+dissect_offered(tvbuff_t *tvb, int offset, packet_info *pinfo,
+               proto_tree *tree, char *drep)
+{
+       offset = dissect_ndr_uint32(
+               tvb, offset, pinfo, tree, drep, hf_offered, NULL);
+
+       return offset;
+}
+
+static int
+dissect_returned(tvbuff_t *tvb, int offset, packet_info *pinfo,
+                proto_tree *tree, char *drep)
+{
+       offset = dissect_ndr_uint32(
+               tvb, offset, pinfo, tree, drep, hf_returned, NULL);
+
+       return offset;
+}
+
+static int
+dissect_unknown(tvbuff_t *tvb, int offset, packet_info *pinfo,
+               proto_tree *tree, char *drep)
+{
+       offset = dissect_ndr_uint32(
+               tvb, offset, pinfo, tree, drep, hf_unknown, NULL);
+
+       return offset;
+}
+
+static int
+RegQueryValue_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
+               proto_tree *tree, char *drep)
+{
+       /* Parse packet */
+
+       offset = dissect_nt_policy_hnd(
+               tvb, offset, pinfo, tree, drep,
+               hf_hnd, NULL, NULL, FALSE, FALSE);
+
+       offset = dissect_ndr_counted_string(
+               tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
+
+       offset = dissect_ndr_pointer(
+               tvb, offset, pinfo, tree, drep,
+               dissect_reserved, NDR_POINTER_UNIQUE,
+               "Reserved", -1);
+
+       offset = dissect_ndr_pointer(
+               tvb, offset, pinfo, tree, drep,
+               dissect_offered, NDR_POINTER_UNIQUE,
+               "Offered", -1);
+
+       offset = dissect_ndr_pointer(
+               tvb, offset, pinfo, tree, drep,
+               dissect_unknown, NDR_POINTER_UNIQUE,
+               "Unknown", -1);
+
+       offset = dissect_ndr_pointer(
+               tvb, offset, pinfo, tree, drep,
+               dissect_unknown, NDR_POINTER_UNIQUE,
+               "Unknown", -1);
+
+       offset = dissect_ndr_pointer(
+               tvb, offset, pinfo, tree, drep,
+               dissect_offered, NDR_POINTER_UNIQUE,
+               "Offered", -1);
+
+       offset = dissect_ndr_pointer(
+               tvb, offset, pinfo, tree, drep,
+               dissect_returned, NDR_POINTER_UNIQUE,
+               "Returned", -1);
+
+       return offset;
+}
+
+static int
+dissect_key_type(tvbuff_t *tvb, int offset, packet_info *pinfo,
+                proto_tree *tree, char *drep)
+{
+       offset = dissect_ndr_uint32(
+               tvb, offset, pinfo, tree, drep, hf_keytype, NULL);
+
+       return offset;
+}
+
+static int
+RegQueryValue_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
+               proto_tree *tree, char *drep)
+{
+       /* Parse packet */
+
+       offset = dissect_ndr_pointer(
+               tvb, offset, pinfo, tree, drep,
+               dissect_key_type, NDR_POINTER_UNIQUE,
+               "Key Type", -1);        
+
+       offset = dissect_ndr_pointer(
+               tvb, offset, pinfo, tree, drep,
+               dissect_ndr_byte_array, NDR_POINTER_UNIQUE,
+               "Key Data", -1);
+
+       offset = dissect_ndr_pointer(
+               tvb, offset, pinfo, tree, drep,
+               dissect_offered, NDR_POINTER_UNIQUE,
+               "Offered", -1);
+
+       offset = dissect_ndr_pointer(
+               tvb, offset, pinfo, tree, drep,
+               dissect_returned, NDR_POINTER_UNIQUE,
+               "Returned", -1);
+
+       offset = dissect_ntstatus(
+               tvb, offset, pinfo, tree, drep, hf_rc, NULL);
 
        return offset;
 }
@@ -458,8 +589,6 @@ RegFoo_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
 
        /* Parse packet */
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
-
        return offset;
 }
 
@@ -474,8 +603,6 @@ RegFoo_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
        offset = dissect_ntstatus(
                tvb, offset, pinfo, tree, drep, hf_rc, NULL);
 
-       dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
-
        return offset;
 }
 
@@ -528,7 +655,7 @@ static dcerpc_sub_dissector dcerpc_reg_dissectors[] = {
         { _REG_UNK_0E, "Unknown0e", NULL, NULL },
         { REG_OPEN_ENTRY, "OpenEntry", RegOpenEntry_q, RegOpenEntry_r },
         { REG_QUERY_KEY, "QueryKey", RegQueryKey_q, RegQueryKey_r },
-        { REG_INFO, "Info", NULL, NULL },
+        { REG_QUERY_VALUE, "QueryValue", RegQueryValue_q, RegQueryValue_r },
         { _REG_UNK_12, "Unknown12", NULL, NULL },
         { _REG_UNK_13, "Unknown13", NULL, NULL },
         { _REG_UNK_14, "Unknown14", NULL, NULL },
@@ -542,37 +669,6 @@ static dcerpc_sub_dissector dcerpc_reg_dissectors[] = {
         { 0, NULL, NULL,  NULL }
 };
 
-static const value_string reg_opnum_vals[] = {
-        { REG_OPEN_HKCR, "OpenHKCR" },
-        { _REG_UNK_01, "Unknown01" },
-        { REG_OPEN_HKLM, "OpenHKLM" },
-        { _REG_UNK_03, "Unknown03" },
-        { REG_OPEN_HKU, "OpenHKU" },
-        { REG_CLOSE, "Close" },
-        { REG_CREATE_KEY, "CreateKey" },
-        { REG_DELETE_KEY, "DeleteKey" },
-        { REG_DELETE_VALUE, "DeleteValue" },
-        { REG_ENUM_KEY, "EnumKey" },
-        { REG_ENUM_VALUE, "EnumValue" },
-        { REG_FLUSH_KEY, "FlushKey" },
-        { REG_GET_KEY_SEC, "GetKeySecurity" },
-        { _REG_UNK_0D, "Unknown0d" },
-        { _REG_UNK_0E, "Unknown0e" },
-        { REG_OPEN_ENTRY, "OpenEntry" },
-        { REG_QUERY_KEY, "QueryKey" },
-        { REG_INFO, "Info" },
-        { _REG_UNK_12, "Unknown12" },
-        { _REG_UNK_13, "Unknown13" },
-        { _REG_UNK_14, "Unknown14" },
-        { REG_SET_KEY_SEC, "SetKeySecurity" },
-        { REG_CREATE_VALUE, "CreateValue" },
-        { _REG_UNK_17, "Unknown17" },
-        { REG_SHUTDOWN, "Shutdown" },
-        { REG_ABORT_SHUTDOWN, "AbortShutdown" },
-        { _REG_UNK_1A, "Unknown1A" },
-       { 0, NULL }
-};
-
 void
 proto_register_dcerpc_reg(void)
 {
@@ -590,12 +686,36 @@ proto_register_dcerpc_reg(void)
 
                { &hf_reg_opnum,
                  { "Operation", "reg.opnum", FT_UINT16, BASE_DEC,
-                   VALS(reg_opnum_vals), 0x0, "Operation", HFILL }},
+                   NULL, 0x0, "Operation", HFILL }},
 
                { &hf_access_mask,
                  { "Access mask", "reg.access_mask", FT_UINT32, BASE_HEX,
                    NULL, 0x0, "Access mask", HFILL }},
 
+               { &hf_keytype,
+                 { "Key type", "reg.type", FT_UINT32, BASE_DEC,
+                   VALS(reg_datatypes), 0x0, "Key type", HFILL }},
+
+               { &hf_keydata,
+                 { "Key data", "reg.data", FT_BYTES, BASE_HEX,
+                   NULL, 0x0, "Key data", HFILL }},
+
+               { &hf_offered,
+                 { "Offered", "reg.offered", FT_UINT32, BASE_DEC,
+                   NULL, 0x0, "Offered", HFILL }},
+
+               { &hf_returned,
+                 { "Returned", "reg.returned", FT_UINT32, BASE_DEC,
+                   NULL, 0x0, "Returned", HFILL }},
+
+               { &hf_reserved,
+                 { "Reserved", "reg.reserved", FT_UINT32, BASE_HEX,
+                   NULL, 0x0, "Reserved", HFILL }},
+
+               { &hf_unknown,
+                 { "Unknown", "reg.unknown", FT_UINT32, BASE_HEX,
+                   NULL, 0x0, "Unknown", HFILL }},
+
                /* OpenHKLM */
 
                { &hf_openhklm_unknown1,