private static List <MimeAppleTranscoder.EntryDescriptor> ReadAppleFileHeaderEntries(Stream applefileStream) { int num = MimeAppleTranscoder.ReadUIntFromStream(applefileStream); if (num != 131072) { throw new MimeException(EmailMessageStrings.WrongAppleVersionNumber); } applefileStream.Position += 16L; int num2 = MimeAppleTranscoder.ReadUShortFromStream(applefileStream); if (num2 > 100) { throw new MimeException(EmailMessageStrings.TooManyEntriesInApplefile); } List <MimeAppleTranscoder.EntryDescriptor> list = new List <MimeAppleTranscoder.EntryDescriptor>(num2); for (int i = 0; i < num2; i++) { int entryId = MimeAppleTranscoder.ReadUIntFromStream(applefileStream); int num3 = MimeAppleTranscoder.ReadUIntFromStream(applefileStream); int num4 = MimeAppleTranscoder.ReadUIntFromStream(applefileStream); if ((long)num3 < applefileStream.Position || (long)num3 > applefileStream.Length || num4 < 0 || (long)(num4 + num3) > applefileStream.Length) { throw new MimeException(EmailMessageStrings.WrongOffsetsInApplefile); } MimeAppleTranscoder.EntryDescriptor item = new MimeAppleTranscoder.EntryDescriptor(entryId, num3, num4); list.Add(item); } list.Sort(new Comparison <MimeAppleTranscoder.EntryDescriptor>(MimeAppleTranscoder.EntryDescriptor.CompareByOffset)); return(list); }
public static int CompareByOffset(MimeAppleTranscoder.EntryDescriptor x, MimeAppleTranscoder.EntryDescriptor y) { int num = x.EntryOffset - y.EntryOffset; if (num == 0) { num = x.EntryLength - y.EntryLength; } return(num); }
private static void AddEntry(List <MimeAppleTranscoder.EntryDescriptor> descriptors, MimeAppleTranscoder.EntryDescriptor descr, ref int virtualOffset) { descriptors.Add(descr); virtualOffset += descr.EntryLength; }
private static void Transcode(Stream applefileStream, Stream dataForkStream, Stream outAttachMacInfo, Stream outMacBinStream, ref Stream outDataForkStream, out string fileName, out byte[] additionalInfo) { if (applefileStream.Length < 26L) { throw new MimeException(EmailMessageStrings.UnexpectedEndOfStream); } int num = MimeAppleTranscoder.ReadUIntFromStream(applefileStream); if (num != 333319 && num != 333312) { if (dataForkStream != null) { throw new MimeException(EmailMessageStrings.WrongAppleMagicNumber); } applefileStream.Position = 0L; MimeAppleTranscoder.MacBinToApplefile(applefileStream, outAttachMacInfo, out fileName, out additionalInfo); applefileStream.Position = 0L; if (outMacBinStream == null) { return; } MimeAppleTranscoder.CopyStreamData(applefileStream, outMacBinStream); return; } else { fileName = null; byte[] array = new byte[128]; array[0] = 0; int num2 = 0; if (dataForkStream != null) { num2 = 83; MimeAppleTranscoder.WriteIntData((int)dataForkStream.Length, array, ref num2); } byte[] bytes = MimeAppleTranscoder.macEncoding.GetBytes("mBIN"); for (int i = 0; i < 4; i++) { array[102 + i] = bytes[i]; } array[122] = 130; array[123] = 129; int inputOffset = 0; MimeAppleTranscoder.EntryDescriptor entryDescriptor = null; int inputOffset2 = 0; List <MimeAppleTranscoder.EntryDescriptor> list = MimeAppleTranscoder.ReadAppleFileHeaderEntries(applefileStream); foreach (MimeAppleTranscoder.EntryDescriptor entryDescriptor2 in list) { switch (entryDescriptor2.EntryId) { case 1: entryDescriptor = entryDescriptor2; num2 = 83; MimeAppleTranscoder.WriteIntData(entryDescriptor2.EntryLength, array, ref num2); break; case 2: inputOffset = entryDescriptor2.EntryOffset; num2 = 87; MimeAppleTranscoder.WriteIntData(entryDescriptor2.EntryLength, array, ref num2); break; case 4: inputOffset2 = entryDescriptor2.EntryOffset; num2 = 99; MimeAppleTranscoder.WriteShortData(entryDescriptor2.EntryLength, array, ref num2); break; } } if (entryDescriptor != null) { list.Remove(entryDescriptor); } if (outAttachMacInfo != null) { MimeAppleTranscoder.WriteApplefileHeader(list, true, outAttachMacInfo); } int num3 = (int)applefileStream.Position; foreach (MimeAppleTranscoder.EntryDescriptor entryDescriptor3 in list) { if (entryDescriptor3.EntryOffset < num3) { throw new MimeException(EmailMessageStrings.WrongOffsetsInApplefile); } if (entryDescriptor3.EntryOffset > num3) { if (applefileStream.Length < (long)entryDescriptor3.EntryOffset) { throw new MimeException(EmailMessageStrings.WrongOffsetsInApplefile); } applefileStream.Position = (long)entryDescriptor3.EntryOffset; } if (entryDescriptor3.EntryLength < 0) { throw new MimeException(EmailMessageStrings.EntryLengthTooBigInApplefile((long)((ulong)entryDescriptor3.EntryLength))); } int num4 = 0; byte[] array2 = null; int entryId = entryDescriptor3.EntryId; if (entryId != 3) { switch (entryId) { case 8: num4 = Math.Min(8, entryDescriptor3.EntryLength); array2 = new byte[num4]; MimeAppleTranscoder.ReadFixed(applefileStream, array2, 0, num4); for (int j = 0; j < num4; j++) { array[91 + j] = array2[j]; } break; case 9: num4 = Math.Min(28, entryDescriptor3.EntryLength); array2 = new byte[num4]; MimeAppleTranscoder.ReadFixed(applefileStream, array2, 0, num4); if (num4 >= 16) { for (int k = 0; k < 16; k++) { array[65 + k] = array2[k]; } array[101] = array[73]; array[73] = array[74]; array[74] = 0; if (num4 >= 22) { array[106] = array2[20]; array[107] = array2[21]; } } break; case 10: num4 = Math.Min(4, entryDescriptor3.EntryLength); array2 = new byte[num4]; MimeAppleTranscoder.ReadFixed(applefileStream, array2, 0, num4); if (num4 == 4) { array[81] = (byte)((array2[3] & 2) >> 1); } break; } } else { num4 = Math.Min(63, entryDescriptor3.EntryLength); array2 = new byte[num4]; MimeAppleTranscoder.ReadFixed(applefileStream, array2, 0, num4); fileName = MimeAppleTranscoder.macEncoding.GetString(array2, 0, num4); array[1] = (byte)num4; for (int l = 0; l < num4; l++) { array[2 + l] = array2[l]; } } if (outAttachMacInfo != null) { if (array2 != null) { outAttachMacInfo.Write(array2, 0, num4); } if (num4 != entryDescriptor3.EntryLength) { MimeAppleTranscoder.CopyStreamData(applefileStream, outAttachMacInfo, new int?(entryDescriptor3.EntryLength - num4)); } } num3 = (int)applefileStream.Position; } num2 = 124; MimeAppleTranscoder.WriteUShortData((int)MimeAppleTranscoder.CalcCRC16(array, 126), array, ref num2); MacBinaryHeader macBinaryHeader = new MacBinaryHeader(array); if (outMacBinStream == null) { additionalInfo = null; if (outDataForkStream != null) { ReadableDataStorageOnStream readableDataStorageOnStream = new ReadableDataStorageOnStream(applefileStream, false); if (entryDescriptor != null) { outDataForkStream = readableDataStorageOnStream.OpenReadStream((long)entryDescriptor.EntryOffset, (long)(entryDescriptor.EntryOffset + (int)macBinaryHeader.DataForkLength)); return; } outDataForkStream = readableDataStorageOnStream.OpenReadStream(0L, 0L); } return; } additionalInfo = MimeAppleTranscoder.EncodeAdditionalInfo(macBinaryHeader.FileCreator, macBinaryHeader.FileType); outMacBinStream.Write(array, 0, array.Length); if (macBinaryHeader.DataForkLength > 0L) { if (dataForkStream != null) { MimeAppleTranscoder.CopyStreamData(dataForkStream, outMacBinStream); MimeAppleTranscoder.WriteMacBinPadding(outMacBinStream, (int)macBinaryHeader.DataForkLength); } else if (entryDescriptor != null) { MimeAppleTranscoder.CopyDataWithPadding(applefileStream, outMacBinStream, entryDescriptor.EntryOffset, (int)macBinaryHeader.DataForkLength); } } if (macBinaryHeader.ResourceForkLength > 0L) { MimeAppleTranscoder.CopyDataWithPadding(applefileStream, outMacBinStream, inputOffset, (int)macBinaryHeader.ResourceForkLength); } if (macBinaryHeader.GetInfoLength > 0) { MimeAppleTranscoder.CopyDataWithPadding(applefileStream, outMacBinStream, inputOffset2, macBinaryHeader.GetInfoLength); } return; } }
public static void MacBinToApplefile(Stream macBinStream, Stream outStream, out string fileName, out byte[] additionalInfo) { MacBinaryHeader macBinaryHeader = MimeAppleTranscoder.ExtractMacBinHeader(macBinStream); fileName = macBinaryHeader.FileName; if (outStream == null) { additionalInfo = null; return; } additionalInfo = MimeAppleTranscoder.EncodeAdditionalInfo(macBinaryHeader.FileCreator, macBinaryHeader.FileType); List <MimeAppleTranscoder.EntryDescriptor> descriptors = new List <MimeAppleTranscoder.EntryDescriptor>(6); int entryOffset = 0; byte[] array = null; if (macBinaryHeader.FileName != null) { MimeAppleTranscoder.EntryDescriptor descr = new MimeAppleTranscoder.EntryDescriptor(3, entryOffset, macBinaryHeader.FileNameLength); try { array = MimeAppleTranscoder.macEncoding.GetBytes(fileName); } catch (ArgumentOutOfRangeException innerException) { throw new MimeException(EmailMessageStrings.MacBinWrongFilename, innerException); } MimeAppleTranscoder.AddEntry(descriptors, descr, ref entryOffset); } MimeAppleTranscoder.EntryDescriptor entryDescriptor = new MimeAppleTranscoder.EntryDescriptor(8, entryOffset, 16); MimeAppleTranscoder.AddEntry(descriptors, entryDescriptor, ref entryOffset); int appleDate = MimeAppleTranscoder.GetAppleDate(macBinaryHeader.CreationDate); int appleDate2 = MimeAppleTranscoder.GetAppleDate(macBinaryHeader.ModificationDate); byte[] array2 = new byte[entryDescriptor.EntryLength]; int num = 0; MimeAppleTranscoder.WriteIntData(appleDate, array2, ref num); MimeAppleTranscoder.WriteIntData(appleDate2, array2, ref num); MimeAppleTranscoder.WriteIntData(0, array2, ref num); MimeAppleTranscoder.WriteIntData(0, array2, ref num); MimeAppleTranscoder.EntryDescriptor entryDescriptor2 = new MimeAppleTranscoder.EntryDescriptor(9, entryOffset, 28); MimeAppleTranscoder.AddEntry(descriptors, entryDescriptor2, ref entryOffset); byte[] array3 = new byte[entryDescriptor2.EntryLength]; num = 0; MimeAppleTranscoder.WriteIntData(macBinaryHeader.FileType, array3, ref num); MimeAppleTranscoder.WriteIntData(macBinaryHeader.FileCreator, array3, ref num); MimeAppleTranscoder.WriteShortData((int)((short)macBinaryHeader.FinderFlags), array3, ref num); MimeAppleTranscoder.WriteShortData((int)((short)macBinaryHeader.YIcon), array3, ref num); MimeAppleTranscoder.WriteShortData((int)((short)macBinaryHeader.XIcon), array3, ref num); MimeAppleTranscoder.WriteShortData((int)((short)macBinaryHeader.FileId), array3, ref num); MimeAppleTranscoder.WriteIntData(0, array3, ref num); MimeAppleTranscoder.WriteIntData(0, array3, ref num); MimeAppleTranscoder.WriteIntData(0, array3, ref num); MimeAppleTranscoder.EntryDescriptor entryDescriptor3 = new MimeAppleTranscoder.EntryDescriptor(10, entryOffset, 4); MimeAppleTranscoder.AddEntry(descriptors, entryDescriptor3, ref entryOffset); byte[] array4 = new byte[entryDescriptor3.EntryLength]; array4[0] = 0; array4[1] = 0; array4[2] = 0; array4[3] = (macBinaryHeader.Protected ? 1 : 0); if (macBinaryHeader.ResourceForkLength > 0L) { MimeAppleTranscoder.EntryDescriptor descr2 = new MimeAppleTranscoder.EntryDescriptor(2, entryOffset, (int)macBinaryHeader.ResourceForkLength); MimeAppleTranscoder.AddEntry(descriptors, descr2, ref entryOffset); } if (macBinaryHeader.GetInfoLength > 0) { MimeAppleTranscoder.EntryDescriptor descr3 = new MimeAppleTranscoder.EntryDescriptor(4, entryOffset, macBinaryHeader.GetInfoLength); MimeAppleTranscoder.AddEntry(descriptors, descr3, ref entryOffset); } MimeAppleTranscoder.WriteApplefileHeader(descriptors, true, outStream); if (array != null) { outStream.Write(array, 0, array.Length); } outStream.Write(array2, 0, array2.Length); outStream.Write(array3, 0, array3.Length); outStream.Write(array4, 0, array4.Length); if (macBinaryHeader.SecondaryHeaderLength > 0) { macBinStream.Position += (long)(macBinaryHeader.SecondaryHeaderLength + MimeAppleTranscoder.GetMacBinPaddingSize(macBinaryHeader.SecondaryHeaderLength)); } if (macBinaryHeader.DataForkLength > 0L) { macBinStream.Position += macBinaryHeader.DataForkLength + (long)MimeAppleTranscoder.GetMacBinPaddingSize((int)macBinaryHeader.DataForkLength); } if (macBinaryHeader.ResourceForkLength > 0L) { MimeAppleTranscoder.CopyStreamData(macBinStream, outStream, new int?((int)macBinaryHeader.ResourceForkLength)); macBinStream.Position += (long)MimeAppleTranscoder.GetMacBinPaddingSize((int)macBinaryHeader.ResourceForkLength); } if (macBinaryHeader.GetInfoLength > 0) { MimeAppleTranscoder.CopyStreamData(macBinStream, outStream, new int?(macBinaryHeader.GetInfoLength)); macBinStream.Position += (long)MimeAppleTranscoder.GetMacBinPaddingSize(macBinaryHeader.GetInfoLength); } }