Skip to content

Commit 8a4a3c1

Browse files
U/sgriffin/mapi (#79)
* Hex arrays should actually be in hex * suppress cb on PtypBinary since we already have Count field * Annotate a few more MAPI data types * quote strings * anotate integer16 * unknown proptag should still be hex * add generic array parsing * Simplify array output * Don't crash copying nothing * Parse StateProperty and add some prop tags
1 parent 54bc2aa commit 8a4a3c1

File tree

6 files changed

+107
-41
lines changed

6 files changed

+107
-41
lines changed

MAPIInspector/Source/MAPIControl.Designer.cs

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MAPIInspector/Source/Parsers/BaseStructure.cs

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ public static TreeNode AddNodesForTree(string nodeName, object obj, int startInd
350350
// the size of underlying type of enum.
351351
Type fieldType = type;
352352

353-
TreeNode tn = new TreeNode(string.Format("{0}:{1}", info[i].Name, EnumToString(info[i].GetValue(obj))));
353+
TreeNode tn = new TreeNode(string.Format("{0}:{1}", info[i].Name, Utilities.EnumToString(info[i].GetValue(obj))));
354354
res.Nodes.Add(tn);
355355

356356
if (type.Name == "String")
@@ -418,19 +418,19 @@ public static TreeNode AddNodesForTree(string nodeName, object obj, int startInd
418418
result.Append(tempbye.ToString("X2"));
419419
}
420420
}
421-
else if (arr.GetType().ToString() == "System.Byte[]")
421+
else if (arr.Length > 0)
422422
{
423-
result.Append(Utilities.ConvertArrayToHexString((byte[])arr));
424-
}
425-
else if (arr.GetType().ToString() == "System.Uint[]")
426-
{
427-
result.Append(Utilities.ConvertArrayToHexString((uint[])arr));
423+
result.Append(Utilities.ConvertArrayToHexString(arr));
428424
}
429425

430426
TreeNode tn = new TreeNode($"{info[i].Name}:{result.ToString()}");
431427
res.Nodes.Add(tn);
432-
// Add subnode with length of array
433-
tn.Nodes.Add(new TreeNode($"cb:{arr.Length}"));
428+
429+
if (!(obj is PtypBinary))
430+
{
431+
// Add subnode with length of array
432+
tn.Nodes.Add(new TreeNode($"cb:{arr.Length}"));
433+
}
434434

435435
for (int j = 0; j < arr.Length; j++)
436436
{
@@ -1007,23 +1007,6 @@ protected long RemainingBytes()
10071007
return this.stream.Length - this.stream.Position;
10081008
}
10091009

1010-
/// <summary>
1011-
/// Converts a simple (non-flag) enum to string. If the value is not present in the underlying enum, converts to a hex string.
1012-
/// </summary>
1013-
/// <param name="obj"></param>
1014-
/// <returns></returns>
1015-
private static string EnumToString(object obj)
1016-
{
1017-
if (Enum.IsDefined(obj.GetType(), obj))
1018-
{
1019-
return obj.ToString();
1020-
}
1021-
else
1022-
{
1023-
return $"0x{Convert.ToUInt64(obj):X}";
1024-
}
1025-
}
1026-
10271010
/// <summary>
10281011
/// Record start position and byte counts consumed
10291012
/// </summary>

MAPIInspector/Source/Parsers/MSOXCDATA.cs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4822,14 +4822,15 @@ public override void Parse(Stream s)
48224822
{
48234823
PropertyValue propValue = new PropertyValue(tempPropTag.PropertyType);
48244824
propValue.Parse(s);
4825-
propValue.PropertyTag = $"{tempPropTag.PropertyType}:{tempPropTag.PropertyId}";
4825+
//todo
4826+
propValue.PropertyTag = $"{tempPropTag.PropertyType}:{Utilities.EnumToString(tempPropTag.PropertyId)}";
48264827
rowPropValue = propValue;
48274828
}
48284829
else
48294830
{
48304831
TypedPropertyValue typePropValue = new TypedPropertyValue();
48314832
typePropValue.Parse(s);
4832-
typePropValue.PropertyTag = $"{tempPropTag.PropertyType}:{tempPropTag.PropertyId}";
4833+
typePropValue.PropertyTag = $"{tempPropTag.PropertyType}:{Utilities.EnumToString(tempPropTag.PropertyId)}";
48334834
rowPropValue = typePropValue;
48344835
}
48354836
}
@@ -4839,14 +4840,14 @@ public override void Parse(Stream s)
48394840
{
48404841
FlaggedPropertyValue flagPropValue = new FlaggedPropertyValue(tempPropTag.PropertyType);
48414842
flagPropValue.Parse(s);
4842-
flagPropValue.PropertyTag = $"{tempPropTag.PropertyType}:{tempPropTag.PropertyId}";
4843+
flagPropValue.PropertyTag = $"{tempPropTag.PropertyType}:{Utilities.EnumToString(tempPropTag.PropertyId)}";
48434844
rowPropValue = flagPropValue;
48444845
}
48454846
else
48464847
{
48474848
FlaggedPropertyValueWithType flagPropValue = new FlaggedPropertyValueWithType();
48484849
flagPropValue.Parse(s);
4849-
flagPropValue.PropertyTag = $"{tempPropTag.PropertyType}:{tempPropTag.PropertyId}";
4850+
flagPropValue.PropertyTag = $"{tempPropTag.PropertyType}:{Utilities.EnumToString(tempPropTag.PropertyId)}";
48504851
rowPropValue = flagPropValue;
48514852
}
48524853
}
@@ -5192,7 +5193,7 @@ public override void Parse(Stream s)
51925193
/// <summary>
51935194
/// 2 bytes; a 16-bit integer. [MS-DTYP]: INT16
51945195
/// </summary>
5195-
public class PtypInteger16 : BaseStructure
5196+
public class PtypInteger16 : AnnotatedData
51965197
{
51975198
/// <summary>
51985199
/// 16-bit integer.
@@ -5207,13 +5208,16 @@ public override void Parse(Stream s)
52075208
{
52085209
base.Parse(s);
52095210
this.Value = this.ReadINT16();
5211+
this.ParsedValue = $"{Value}";
52105212
}
5213+
5214+
public override int Size { get; } = 2;
52115215
}
52125216

52135217
/// <summary>
52145218
/// 4 bytes; a 32-bit integer. [MS-DTYP]: INT32
52155219
/// </summary>
5216-
public class PtypInteger32 : BaseStructure
5220+
public class PtypInteger32 : AnnotatedData
52175221
{
52185222
/// <summary>
52195223
/// 32-bit integer.
@@ -5228,7 +5232,10 @@ public override void Parse(Stream s)
52285232
{
52295233
base.Parse(s);
52305234
this.Value = this.ReadINT32();
5235+
this.ParsedValue = $"{Value}";
52315236
}
5237+
5238+
public override int Size { get; } = 4;
52325239
}
52335240

52345241
/// <summary>
@@ -5339,7 +5346,7 @@ public override void Parse(Stream s)
53395346
/// <summary>
53405347
/// 1 byte; restricted to 1 or 0.
53415348
/// </summary>
5342-
public class PtypBoolean : BaseStructure
5349+
public class PtypBoolean : AnnotatedData
53435350
{
53445351
/// <summary>
53455352
/// 1 byte; restricted to 1 or 0.
@@ -5354,7 +5361,10 @@ public override void Parse(Stream s)
53545361
{
53555362
base.Parse(s);
53565363
this.Value = this.ReadBoolean();
5364+
this.ParsedValue = Value.ToString();
53575365
}
5366+
5367+
public override int Size { get; } = 1;
53585368
}
53595369

53605370
/// <summary>
@@ -5381,7 +5391,7 @@ public override void Parse(Stream s)
53815391
/// <summary>
53825392
/// Variable size; a string of Unicode characters in UTF-16LE format encoding with terminating null character (0x0000).
53835393
/// </summary>
5384-
public class PtypString : BaseStructure
5394+
public class PtypString : AnnotatedData
53855395
{
53865396
/// <summary>
53875397
/// A string of Unicode characters in UTF-16LE format encoding with terminating null character (0x0000).
@@ -5411,6 +5421,12 @@ public override void Parse(Stream s)
54115421
base.Parse(s);
54125422
this.Value = new MAPIString(Encoding.Unicode, "\0", this.length);
54135423
this.Value.Parse(s);
5424+
this.ParsedValue = $"\"{Value}\"";
5425+
}
5426+
5427+
public override int Size
5428+
{
5429+
get { return Value.Size; }
54145430
}
54155431
}
54165432

MAPIInspector/Source/Parsers/MSOXCFXICS.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2576,7 +2576,7 @@ public class RopSynchronizationUploadStateStreamBeginRequest : BaseStructure
25762576
/// <summary>
25772577
/// A PropertyTag structure.
25782578
/// </summary>
2579-
public uint StateProperty;
2579+
public PropertyTag StateProperty;
25802580

25812581
/// <summary>
25822582
/// An unsigned integer that specifies the size of the stream to be uploaded.
@@ -2594,7 +2594,9 @@ public override void Parse(Stream s)
25942594
this.RopId = (RopIdType)this.ReadByte();
25952595
this.LogonId = this.ReadByte();
25962596
this.InputHandleIndex = this.ReadByte();
2597-
this.StateProperty = this.ReadUint();
2597+
this.StateProperty = new PropertyTag();
2598+
this.StateProperty.Parse(s);
2599+
25982600
this.TransferBufferSize = this.ReadUint();
25992601
}
26002602
}

MAPIInspector/Source/Parsers/MSOXPROPS.cs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2867,7 +2867,52 @@ public enum PidTagPropertyEnum : ushort
28672867
/// <summary>
28682868
/// The MetaTagDnPrefix meta-property MUST be ignored when received
28692869
/// </summary>
2870-
MetaTagDnPrefix = 0x4008
2870+
MetaTagDnPrefix = 0x4008,
2871+
2872+
/// <summary>
2873+
/// Contains a count of the significant characters of the message text.
2874+
/// </summary>
2875+
PidTagRtfSyncBodyCount = 0x1007,
2876+
2877+
/// <summary>
2878+
/// Contains significant characters that appear at the beginning of the message text.
2879+
/// </summary>
2880+
PidTagRtfSyncBodyTag = 0x1008,
2881+
2882+
/// <summary>
2883+
/// Contains a count of the ignorable characters that appear before the significant characters of the message.
2884+
/// </summary>
2885+
PidTagRtfSyncPrefixCount = 0x1010,
2886+
2887+
/// <summary>
2888+
/// Contains a count of the ignorable characters that appear after the significant characters of the message.
2889+
/// </summary>
2890+
PidTagRtfSyncTrailingCount = 0x1011,
2891+
2892+
/// <summary>
2893+
/// The OrigEntryId
2894+
/// </summary>
2895+
OrigEntryId = 0x300F,
2896+
2897+
/// <summary>
2898+
/// he MetaTagIdsetGiven property contains a serialization of REPLGUID-based IDSET structures, as specified in section 2.2.2.4.2.
2899+
/// </summary>
2900+
MetaTagIdsetGiven = 0x4017,
2901+
2902+
/// <summary>
2903+
/// The MetaTagCnsetSeen property contains a serialization of REPLGUID-based CNSET structures, as specified in section 2.2.2.4.
2904+
/// </summary>
2905+
MetaTagCnsetSeen = 0x6796,
2906+
2907+
/// <summary>
2908+
/// The MetaTagCnsetRead property contains a serialization of REPLGUID-based CNSET structures, as specified in section 2.2.2.4.
2909+
/// </summary>
2910+
MetaTagCnsetRead = 0x67D2,
2911+
2912+
/// <summary>
2913+
/// The MetaTagCnsetSeenFAI property contains a serialization of REPLGUID-based IDSET structures, as specified in section 2.2.2.4.
2914+
/// </summary>
2915+
MetaTagCnsetSeenFAI = 0x67DA
28712916
}
28722917

28732918
/// <summary>

MAPIInspector/Source/Utilities.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@ public static string ConvertByteArrayToString(byte[] bin, uint? limit = null)
6161
}
6262

6363
// Array type just display the first 30 values if the array length is more than 30.
64-
public static string ConvertArrayToHexString<T>(T[] bin, int? limit = 30)
64+
public static string ConvertArrayToHexString(Array bin, int? limit = 30)
6565
{
6666
var result = new StringBuilder();
67-
int displayLength = limit.HasValue ? limit.Value : bin.Length;
67+
int displayLength = limit ?? bin.Length;
6868
result.Append("[");
6969

7070
foreach (var b in bin)
7171
{
72-
result.Append(b.ToString() + ",");
72+
result.Append($"{b:X2},");
7373

7474
if (displayLength <= 1)
7575
{
@@ -213,5 +213,22 @@ public static string ConvertCSharpToJson(int id, bool isRequest, object obj)
213213
SealTheObject sealTheObject = new SealTheObject(id, isRequest, obj);
214214
return JsonConvert.SerializeObject((object)sealTheObject);
215215
}
216+
217+
/// <summary>
218+
/// Converts a simple (non-flag) enum to string. If the value is not present in the underlying enum, converts to a hex string.
219+
/// </summary>
220+
/// <param name="obj"></param>
221+
/// <returns></returns>
222+
public static string EnumToString(object obj)
223+
{
224+
if (Enum.IsDefined(obj.GetType(), obj))
225+
{
226+
return obj.ToString();
227+
}
228+
else
229+
{
230+
return $"0x{Convert.ToUInt64(obj):X}";
231+
}
232+
}
216233
}
217234
}

0 commit comments

Comments
 (0)