private OleObject ReadOLE(BinaryReader reader) { OleObject res = new OleObject(); // read chunk version ushort version = reader.ReadUInt16(); reader.ReadUInt16(); // version can be whatever according to MS-OLEDS; thus skip uint formatId = reader.ReadUInt32(); if (formatId < 1 || formatId > 3) { formatId = 0; } res.Format = (OleType)formatId; // class string uint stringLength = reader.ReadUInt32(); byte[] stringData = reader.ReadBytes((int)stringLength); res.ClassString = CutAtNullTerminator(Encoding.ASCII.GetString(stringData)); if (formatId == 3) { // static uint width = reader.ReadUInt32(); uint height = reader.ReadUInt32(); // size and data uint staticDataLength = reader.ReadUInt32(); res.StaticData = reader.ReadBytes((int)staticDataLength); } else { // topic string reader.BaseStream.Seek(reader.ReadUInt32(), SeekOrigin.Current); // item string reader.BaseStream.Seek(reader.ReadUInt32(), SeekOrigin.Current); if (formatId == 2) { // embedded. native data & size uint staticDataLength = reader.ReadUInt32(); res.StaticData = reader.ReadBytes((int)staticDataLength); } else { // linked. network name uint networkNameLength = reader.ReadUInt32(); byte[] networkNameData = reader.ReadBytes((int)networkNameLength); res.NetworkName = CutAtNullTerminator(Encoding.ASCII.GetString(networkNameData)); reader.BaseStream.Seek(reader.ReadUInt32(), SeekOrigin.Current); // network type res.NetworkType = reader.ReadUInt32(); // link options res.LinkOption = reader.ReadUInt32(); SkipPresentationObj(reader); } } return(res); }
private bool TryParseOleAttachment(OleObject obj, ref AttachmentFile attachment) { if (obj.ClassString == "SoundRec") { attachment = new AttachmentFile("SOUND.WAV", "audio/wav", obj.StaticData); return(true); } if (obj.ClassString == "PBrush") { attachment = new AttachmentFile("IMAGE.BMP", "image/bmp", obj.StaticData); return(true); } if (obj.ClassString == "Package") { attachment = new AttachmentFile("PACKAGE.OLE", "application/octet-stream", obj.StaticData); return(true); } return(false); }
private void ReadDKO(Cardfile file, BinaryReader reader) { uint nextObjectID = reader.ReadUInt32(); ushort cardCount = reader.ReadUInt16(); long oldPosition; for (int i = 0; i < cardCount; ++i) { reader.BaseStream.Seek(6, SeekOrigin.Current); // read card info uint pos = reader.ReadUInt32(); byte flags = reader.ReadByte(); byte[] titleRaw = reader.ReadBytes(82); string index = ReadNullTerminated16String(titleRaw); oldPosition = reader.BaseStream.Position; // read card reader.BaseStream.Seek(pos, SeekOrigin.Begin); ushort objectFlags = reader.ReadUInt16(); AttachmentFile attachment = null; if (objectFlags != 0) { // contains OLE object uint objectId = reader.ReadUInt32(); // get length of OLE object by skipping over it long beforeObj = reader.BaseStream.Position; OleObject obj = ReadOLE(reader); long oleObjLen = reader.BaseStream.Position - beforeObj; reader.BaseStream.Seek(beforeObj, SeekOrigin.Begin); obj.Data = reader.ReadBytes((int)oleObjLen); bool customAttachment = false; if (obj.Format == OleType.Static || obj.Format == OleType.Embedded) { customAttachment = TryParseOleAttachment(obj, ref attachment); } if (!customAttachment) { attachment = new AttachmentFile("OBJECT.OLE", "application/octet-stream", obj.Data); } // then skip other attributes /*ushort charWidth =*/ reader.ReadUInt16(); /*ushort charHeight =*/ reader.ReadUInt16(); /*ushort rectLeft =*/ reader.ReadUInt16(); /*ushort rectTop =*/ reader.ReadUInt16(); /*ushort rectRight =*/ reader.ReadUInt16(); /*ushort rectBottom =*/ reader.ReadUInt16(); /*ushort objectType =*/ reader.ReadUInt16(); } ushort textlen = reader.ReadUInt16(); byte[] textRaw = reader.ReadBytes(textlen * 2 + 3); string text = ReadNullTerminated16String(textRaw); reader.BaseStream.Seek(oldPosition, SeekOrigin.Begin); Card card = new Card(index, text); if (attachment != null) { card.Attachment = attachment; } file.AddCard(card); } }