/// <summary> /// Process a TNEF-encoded message and return an object with the message's body, content type, and attachments. /// </summary> public TnefEncoding(byte[] TnefEncodedBytes) { MimeAttachments = new List<MimePart>(); // Confirm the TNEF signature. uint signature = ReadUint32(TnefEncodedBytes); if (signature == 0x223E9F78) { uint referenceKey = ReadUint16(TnefEncodedBytes); // Variables to track the last attachment properties discovered. string currentAttachmentFileName = ""; byte[] currentAttachmentBody = null; // Loop through each TNEF-encoded component. while (Cursor < TnefEncodedBytes.Length) { byte headerComponent = TnefEncodedBytes[Cursor++]; uint headerType = ReadUint16(TnefEncodedBytes) & 0x0000FFFF; uint headerId = ReadUint16(TnefEncodedBytes); uint headerSize = ReadUint32(TnefEncodedBytes); if (headerSize > 0) { // Load the data of this TNEF component into its own array. byte[] data = new byte[headerSize]; Buffer.BlockCopy(TnefEncodedBytes, Cursor, data, 0, (int)headerSize); Cursor += (int)headerSize; // Require valid checksums. uint readChecksum = ReadUint16(TnefEncodedBytes); uint calculatedChecksum = CalculateChecksum(data); if (readChecksum == calculatedChecksum) { // Process only the TNEF components related to the body and attachments. switch (headerType) { case 0x0000: // Owner case 0x0001: // Sent For case 0x0002: // Delegate case 0x0006: // Date Start case 0x0007: // Date End case 0x0008: // Owner Appt ID case 0x0009: // Response Requested case 0x8000: // From case 0x8004: // Subject case 0x8005: // Date Sent case 0x8006: // Date Received case 0x8007: // Flags case 0x8008: // Message Class case 0x8009: // Message ID case 0x800A: // Parent ID case 0x800B: // Conversation ID case 0x800C: // Body case 0x800D: // Priority break; case 0x800F: // Attachment Data // Check if we've already found this attachment's filename, and if so, record it. if (!string.IsNullOrEmpty(currentAttachmentFileName)) { MimeAttachments.Add(new MimePart(currentAttachmentFileName, Functions.GetDefaultContentTypeForExtension(currentAttachmentFileName), "", "", "", data)); currentAttachmentFileName = ""; } else currentAttachmentBody = data; break; case 0x8010: // Attachment Title // Check if we've already found this attachment's contents, and if so, record it. if (currentAttachmentBody != null) { MimeAttachments.Add(new MimePart(ParseNullTerminatedString(Encoding.UTF8.GetString(data)), Functions.GetDefaultContentTypeForExtension(ParseNullTerminatedString(Encoding.UTF8.GetString(data))), "", "", "", currentAttachmentBody)); currentAttachmentBody = null; } else currentAttachmentFileName = ParseNullTerminatedString(Encoding.UTF8.GetString(data)); break; case 0x8011: // Attachment Rendering case 0x8012: // Attachment Creation Date case 0x8013: // Attachment Modified Date case 0x8020: // Modified Date case 0x9001: // Attachment Transport Name case 0x9002: // Attachment Rendering Data case 0x9003: // MAPI Properties if (data.Length > 16) { // Attempt to unpack the MAPI properties. MapiProperties props = new MapiProperties(data); if (!string.IsNullOrEmpty(props.Body)) { Body = props.Body; ContentType = props.ContentType; } } break; case 0x9004: // Recipients Table case 0x9005: // Attachment case 0x9006: // TNEF Version case 0x9007: // OEM Code Page case 0x9008: // Original Message Class break; } } } } } }
/// <summary> /// Process a TNEF-encoded message and return an object with the message's body, content type, and attachments. /// </summary> public TnefEncoding(byte[] TnefEncodedBytes) { MimeAttachments = new List <MimePart>(); // Confirm the TNEF signature. uint signature = ReadUint32(TnefEncodedBytes); if (signature == 0x223E9F78) { uint referenceKey = ReadUint16(TnefEncodedBytes); // Variables to track the last attachment properties discovered. string currentAttachmentFileName = ""; byte[] currentAttachmentBody = null; // Loop through each TNEF-encoded component. while (Cursor < TnefEncodedBytes.Length) { byte headerComponent = TnefEncodedBytes[Cursor++]; uint headerType = ReadUint16(TnefEncodedBytes) & 0x0000FFFF; uint headerId = ReadUint16(TnefEncodedBytes); uint headerSize = ReadUint32(TnefEncodedBytes); if (headerSize > 0) { // Load the data of this TNEF component into its own array. byte[] data = new byte[headerSize]; Buffer.BlockCopy(TnefEncodedBytes, Cursor, data, 0, (int)headerSize); Cursor += (int)headerSize; // Require valid checksums. uint readChecksum = ReadUint16(TnefEncodedBytes); uint calculatedChecksum = CalculateChecksum(data); if (readChecksum == calculatedChecksum) { // Process only the TNEF components related to the body and attachments. switch (headerType) { case 0x0000: // Owner case 0x0001: // Sent For case 0x0002: // Delegate case 0x0006: // Date Start case 0x0007: // Date End case 0x0008: // Owner Appt ID case 0x0009: // Response Requested case 0x8000: // From case 0x8004: // Subject case 0x8005: // Date Sent case 0x8006: // Date Received case 0x8007: // Flags case 0x8008: // Message Class case 0x8009: // Message ID case 0x800A: // Parent ID case 0x800B: // Conversation ID case 0x800C: // Body case 0x800D: // Priority break; case 0x800F: // Attachment Data // Check if we've already found this attachment's filename, and if so, record it. if (!string.IsNullOrEmpty(currentAttachmentFileName)) { MimeAttachments.Add(new MimePart(currentAttachmentFileName, Functions.GetDefaultContentTypeForExtension(currentAttachmentFileName), "", "", "", data)); currentAttachmentFileName = ""; } else { currentAttachmentBody = data; } break; case 0x8010: // Attachment Title // Check if we've already found this attachment's contents, and if so, record it. if (currentAttachmentBody != null) { MimeAttachments.Add(new MimePart(ParseNullTerminatedString(Encoding.UTF8.GetString(data)), Functions.GetDefaultContentTypeForExtension(ParseNullTerminatedString(Encoding.UTF8.GetString(data))), "", "", "", currentAttachmentBody)); currentAttachmentBody = null; } else { currentAttachmentFileName = ParseNullTerminatedString(Encoding.UTF8.GetString(data)); } break; case 0x8011: // Attachment Rendering case 0x8012: // Attachment Creation Date case 0x8013: // Attachment Modified Date case 0x8020: // Modified Date case 0x9001: // Attachment Transport Name case 0x9002: // Attachment Rendering Data case 0x9003: // MAPI Properties if (data.Length > 16) { // Attempt to unpack the MAPI properties. MapiProperties props = new MapiProperties(data); if (!string.IsNullOrEmpty(props.Body)) { Body = props.Body; ContentType = props.ContentType; } } break; case 0x9004: // Recipients Table case 0x9005: // Attachment case 0x9006: // TNEF Version case 0x9007: // OEM Code Page case 0x9008: // Original Message Class break; } } } } } }