IFFRESULT IFFParser::IFFDescendChunk(IFFCHUNK* lpck) { lpck->flags = 0; // Read ULONG len = IFFReadChunkBytes(lpck, IFFCHUNKSIZE); if (len == 0) return IFF_EOF; else if (len != IFFCHUNKSIZE) return IFFERR_READWRITE; lpck->ckID = BigEndian32(lpck->ckID); lpck->ckSize = BigEndian32(lpck->ckSize); lpck->dataOffset = SetFilePos(0, IO::STREAM_SEEK_CUR); lpck->grpID = 0; if (lpck->ckID == ID_FORM) { if (IFFReadChunkBytes(&lpck->grpID, sizeof(ID)) != sizeof(ID)) return IFFERR_READWRITE; lpck->grpID = BigEndian32(lpck->grpID); return IFF_EOC; } return IFF_OK; }
/////////////////// // Read Header int PSDParser::ReadPSDHeader() { m_file->Read(&m_hdr, sizeof(PSDHEADER)); // Check if this is a PSD image if (m_hdr.signature != PSD_SIG) { return -1; } m_hdr.version = BigEndian16(m_hdr.version); m_hdr.channels = BigEndian16(m_hdr.channels); m_hdr.rows = BigEndian32(m_hdr.rows); m_hdr.cols = BigEndian32(m_hdr.cols); m_hdr.depth = BigEndian16(m_hdr.depth); m_hdr.mode = BigEndian16(m_hdr.mode); // Check if we support version number if (m_hdr.version != 1) { //sprintf(r->errorMsg, "Unsupported version: %d", hdr->version); return -2;//result = -1;//PLUGIN_MSG; //goto cleanup; } if ((m_hdr.depth != 1) && (m_hdr.depth != 8) && (m_hdr.depth != 16)) { //sprintf(r->errorMsg, "Unsupported depth: %d", hdr->depth); return -3;//result = -1;//PLUGIN_MSG; //goto cleanup; } /* if ((hdr->mode != MODE_RGB) && (hdr->mode != MODE_Grayscale) && (hdr->mode != MODE_Duotone) && (hdr->mode != MODE_Bitmap) && (hdr->mode != MODE_Indexed) && (hdr->mode != MODE_CMYK)) { switch (hdr->mode) { // case MODE_CMYK: strcpy(r->errorMsg, "Currently unsupported CMYK Imagemode"); // break; case MODE_Multi: strcpy(r->errorMsg, "Currently unsupported MultiChannel Imagemode"); break; case MODE_Lab: strcpy(r->errorMsg, "Currently unsupported Lab Imagemode"); break; default: sprintf(r->errorMsg, "Unsupported Imagemode %d", hdr->mode); } result = PLUGIN_MSG; goto cleanup; } */ return 0; }
ErrorCode Atom::Descend(Stream& stream) { m_pos = stream.Seek(0, IO::STREAM_SEEK_CUR); ULONG nRead; uint32 size; nRead = stream.Read(&size, 4); size = BigEndian32(size); if (nRead == 0) return Success_False; nRead = stream.Read(&m_atomtype, 4); if (size == 1) { nRead = stream.Read(&m_size, 8); // TODO endian ASSERT(0); } else m_size = size; if (m_atomtype == ID_uuid) { nRead = stream.Read(&m_usertype, 16); } m_contentpos = stream.Seek(0, System::IO::STREAM_SEEK_CUR); m_contentsize = m_size - (m_contentpos - m_pos); return Success; }
LONG IFFParser::IFFCreateChunk(IFFCHUNK* lpck) { lpck->flags = 1; // Created IFFCHUNK ck; ck.ckID = BigEndian32(lpck->ckID); ck.ckSize = BigEndian32(lpck->ckSize); m_stream->Write(&ck, IFFCHUNKSIZE); lpck->dataOffset = SetFilePos(0, IO::STREAM_SEEK_CUR); if (lpck->ckID == ID_FORM) { ULONG grpID = BigEndian32(lpck->grpID); m_stream->Write(&grpID, 4); } return IFF_OK; }
ErrorCode MovieHeader::Read(Stream& stream) { ULONG nRead; uint32 verflags; nRead = stream.Read(&verflags, 4); verflags = BigEndian32(verflags); uint8 version = (uint8)(verflags>>24); if (version == 1) { ULONGLONG creationTime; nRead = stream.Read(&creationTime, 8); ULONGLONG modificationTime; nRead = stream.Read(&modificationTime, 8); nRead = stream.Read(&m_timeScale, 4); m_timeScale = BigEndian32(m_timeScale); ULONGLONG duration; nRead = stream.Read(&duration, 8); } else if (version == 0) { ULONG creationTime; nRead = stream.Read(&creationTime, 4); ULONG modificationTime; nRead = stream.Read(&modificationTime, 4); nRead = stream.Read(&m_timeScale, 4); m_timeScale = BigEndian32(m_timeScale); ULONG duration; nRead = stream.Read(&duration, 4); } else ASSERT(0); return Success; }
///////////////// // Skip Resources void PSDParser::SkipPSDResources() { uint32 imgresLength; m_file->Read(&imgresLength, 4); imgresLength = BigEndian32(imgresLength); if (imgresLength > 0) { m_file->Seek(imgresLength, IO::STREAM_SEEK_CUR); } }
/////////////////// // Read Color table // // CTableLength = returns number of colors // void PSDParser::ReadColorTable(uint32* CTableLength, uint8* colortable) { uint32 ctableLength; m_file->Read(&ctableLength, 4); ctableLength = BigEndian32(ctableLength); if (ctableLength > 0) { m_file->Read(colortable, ctableLength); } *CTableLength = ctableLength; }
int PSDParser::Load(IO::ISequentialByteStream* file) { int result = 0; m_file = file; // Header result = ReadPSDHeader(); if (result < 0) return result; // Color table ReadColorTable(&m_ctableLength, (uint8*)m_colortable); // LARGE_INTEGER li; // li.QuadPart = 0; // Get resources file offset, read resources later, but for now, Skip resources m_resOffset = m_file->Seek(0, IO::STREAM_SEEK_CUR); /*result =*/ SkipPSDResources(); //if (FAILED(result)) throw -1;//return result; // Layer/Mask m_file->Read(&m_layermaskLength, 4); m_layermaskLength = BigEndian32(m_layermaskLength); m_layermaskStartPos = m_file->Seek(0, IO::STREAM_SEEK_CUR); if (m_layermaskLength > 0) { ParsePSDLayers(); } // Image resource #if 0 if (r->GetFilePos(r->file) < r->fileSize) { psdfile->bHasMergedImage = TRUE; } #endif return 0; }
IFFRESULT IFFParser::IFFAscendChunk(IFFCHUNK* lpck) { ULONGLONG pos; pos = SetFilePos(0, IO::STREAM_SEEK_CUR); // Current position if (lpck->flags == 0) { int32 offset = lpck->ckSize-(pos-lpck->dataOffset); if (lpck->ckSize & 1) offset++; // Word-aligned chunks /*if (*/SetFilePos(offset, IO::STREAM_SEEK_CUR);// == 0xffffffff) /* return IFFERR_READWRITE; else return IFF_OK; */ } else { uint32 cksize = pos - lpck->dataOffset; if (lpck->ckSize == 0) // Unknown size data at time of chunk creation { lpck->ckSize = cksize; cksize = BigEndian32(cksize); SetFilePos(lpck->dataOffset-4, IO::STREAM_SEEK_SET); IFFWriteChunkBytes(&cksize, 4); // Write the chunk length SetFilePos(pos, IO::STREAM_SEEK_SET); } if (cksize & 1) { uint8 padbyte = 0; IFFWriteChunkBytes(&padbyte, 1); } } return IFF_OK; }
void PSDParser::ParsePSDLayers() { long result = 0; if (m_hdr.depth != 8) { //strcpy(r->errorMsg, "Doesn't support multiple layers with depth != 8"); throw -1; } m_file->Read(&m_layerinfoLength, 4); m_layerinfoLength = BigEndian32(m_layerinfoLength); m_layerinfoStartPos = m_file->Seek(0, IO::STREAM_SEEK_CUR); /* numLayers: If <0, then number of layers is absolute value, and the first alpha channel contains the transparency data for the merged result. */ m_file->Read(&m_numLayers, 2); m_numLayers = BigEndian16(m_numLayers); int numChannels = 0; int numLayers = m_numLayers; if (numLayers < 0) { numLayers = -numLayers; } TRACE("numLayers: %d\n", numLayers); /* if (numLayers > 512) // Sensitive max limit { // strcpy(r->errorMsg, "Too many layers\nNotify author"); // return PLUGIN_MSG; numLayers = 512; } */ //m_layerList = (PSDLAYER*)r->basic->AllocBuffer(sizeof(PSDLAYER)*numLayers, TRUE); /* psdfile->layerinfo = (LAYERINFO*)r->buffer->AllocBuffer(sizeof(LAYERINFO)*numLayers, TRUE); psdfile->layerinfo2 = (LAYERINFO2*)r->buffer->AllocBuffer(sizeof(LAYERINFO2)*numLayers, TRUE); psdfile->layermaskinfo = (LAYERMASKINFO*)r->buffer->AllocBuffer(sizeof(LAYERMASKINFO)*numLayers, TRUE); psdfile->channelinfo = (CHANNELINFO (*)[8])r->buffer->AllocBuffer(sizeof(CHANNELINFO)*numLayers, TRUE); psdfile->layernames = (char (*)[256])r->buffer->AllocBuffer(256*numLayers, TRUE); */ /* psdfile->layerinfo = new LAYERINFO[numLayers]; psdfile->layerinfo2 = new LAYERINFO2[numLayers]; psdfile->layermaskinfo = new LAYERMASKINFO[numLayers]; psdfile->channelinfo = new CHANNELINFO[numLayers][8]; psdfile->layernames = new char[numLayers][256]; */ /* uint32* layerID = new uint32[numLayers]; // Layer id's uint32* layerMaskID = new uint32[numLayers]; // Layer id's BYTE* layerType = new BYTE[numLayers]; // Layer types ZeroMemory(layerID, numLayers*sizeof(uint32)); ZeroMemory(layerMaskID, numLayers*sizeof(uint32)); ZeroMemory(layerType, numLayers*sizeof(BYTE)); */ int lay; for (lay = 0; lay < numLayers; lay++) { TRACE("Layerinfo: %d\n", lay); PSDLayer* psdlayer = new PSDLayer; psdlayer->m_file = this; m_layerList.push_back(psdlayer); m_file->Read(&psdlayer->layerinfo, sizeof(LAYERINFO)); psdlayer->layerinfo.rect.left = BigEndian32(psdlayer->layerinfo.rect.left); psdlayer->layerinfo.rect.top = BigEndian32(psdlayer->layerinfo.rect.top); psdlayer->layerinfo.rect.right = BigEndian32(psdlayer->layerinfo.rect.right); psdlayer->layerinfo.rect.bottom = BigEndian32(psdlayer->layerinfo.rect.bottom); psdlayer->layerinfo.channels = BigEndian16(psdlayer->layerinfo.channels); TRACE("\tchannels: %d\n", psdlayer->layerinfo.channels); TRACE("\t"); numChannels += psdlayer->layerinfo.channels; for (int ch = 0; ch < psdlayer->layerinfo.channels; ch++) { m_file->Read(&psdlayer->channelinfo[ch], sizeof(CHANNELINFO)); psdlayer->channelinfo[ch].channelID = BigEndian16(psdlayer->channelinfo[ch].channelID); psdlayer->channelinfo[ch].length = BigEndian32(psdlayer->channelinfo[ch].length); TRACE("%d, ", psdlayer->channelinfo[ch].channelID); } TRACE("\n"); m_file->Read(&psdlayer->layerinfo2, sizeof(LAYERINFO2)); if (psdlayer->layerinfo2.signature != ID_8BIM) { //strcpy(r->errorMsg, "Wrong layer signature"); //result = -1; throw -1; } // TRACE("\tFlags: %d\n", psdfile->layerinfo2[lay].flags); // TRACE("\tClipping: %d\n", psdfile->layerinfo2[lay].clipping); psdlayer->layerinfo2.extra = BigEndian32(psdlayer->layerinfo2.extra); uint32 startPos = m_file->Seek(0, IO::STREAM_SEEK_CUR); // Layer mask data info uint32 layermaskdatasize; m_file->Read(&layermaskdatasize, 4); layermaskdatasize = BigEndian32(layermaskdatasize); // size += 4; if (layermaskdatasize > 0) { // should be 20 bytes TRACE("\tLayermaskdatasize:\n", layermaskdatasize); if (layermaskdatasize != 20) TRACE("layermaskdatasize != 20\n"); m_file->Read(&psdlayer->layermaskinfo, sizeof(LAYERMASKINFO)); // size += sizeof(LAYERMASKINFO); psdlayer->layermaskinfo.rect.left = BigEndian32(psdlayer->layermaskinfo.rect.left); psdlayer->layermaskinfo.rect.top = BigEndian32(psdlayer->layermaskinfo.rect.top); psdlayer->layermaskinfo.rect.right = BigEndian32(psdlayer->layermaskinfo.rect.right); psdlayer->layermaskinfo.rect.bottom = BigEndian32(psdlayer->layermaskinfo.rect.bottom); // str.Format("flags: %d", layermaskinfo[lay].flags); m_file->Seek(layermaskdatasize-sizeof(LAYERMASKINFO), IO::STREAM_SEEK_CUR); //r->SetFilePos(r->file, layermaskdatasize-sizeof(LAYERMASKINFO), FILE_CURRENT); // size += layermaskdatasize-sizeof(LAYERMASKINFO); } // Layer blending range info, currently skip this uint32 layerblendingsize; m_file->Read(&layerblendingsize, 4); layerblendingsize = BigEndian32(layerblendingsize); // size += 4; if (layerblendingsize > 0) TRACE("\tblending %d\n", layerblendingsize); m_file->Seek(layerblendingsize, IO::STREAM_SEEK_CUR); // size += layerblendingsize; uint8 layerNameLength; m_file->Read(&layerNameLength, 1); // size += 1; m_file->Read(psdlayer->layername, layerNameLength); psdlayer->layername[layerNameLength] = '\0'; // Null terminate // size += layerNameLength; // uint16 rlength = ((layerNameLength+4)/4)*4; uint16 rlength = (layerNameLength+3) & ~3; m_file->Seek(rlength-layerNameLength-1, IO::STREAM_SEEK_CUR); // size += rlength-layerNameLength-1; // Skip remaining extra stuff uint32 endPos = m_file->Seek(0, IO::STREAM_SEEK_CUR); uint32 readLength = endPos-startPos; uint32 extraSize = psdlayer->layerinfo2.extra - readLength; if (extraSize < 0) { //strcpy(r->errorMsg, "PSD: extraSize < 0, something wrong with the file?"); throw -1;//return -1;//PLUGIN_MSG; } else if (extraSize > 0) // Adjustment layer (?) { int end = m_file->Seek(0, IO::STREAM_SEEK_CUR) + extraSize; int blockstart; while ((blockstart = m_file->Seek(0, IO::STREAM_SEEK_CUR)) < end) { ADJUSTMENTINFO adjustInfo; m_file->Read(&adjustInfo, sizeof(adjustInfo)); adjustInfo.length = BigEndian32(adjustInfo.length); //li.QuadPart = extraSize; ASSERT(adjustInfo.signature == ID_8BIM); if (adjustInfo.key == ADJUST_BRIGHTNESS) { BRIGHTNESS brightness; m_file->Read(&brightness, sizeof(BRIGHTNESS)); psdlayer->m_key = adjustInfo.key; psdlayer->m_brightness = brightness; //psdlayer->m_records.push_back(&psdlayer->m_brightness); } m_file->Seek(blockstart + 12 + adjustInfo.length, IO::STREAM_SEEK_CUR); } m_file->Seek(end, IO::STREAM_SEEK_SET); // HandleAdjustmentLayer(); } // Add the layer bool hasalpha = false; bool haslayermask = false; /* { for (int ch = 0; ch < psdfile->layerinfo[lay].channels; ch++) { if (psdfile->channelinfo[lay][ch].channelID == -1) hasalpha = TRUE; else if (psdfile->channelinfo[lay][ch].channelID == -2) haslayermask = TRUE; } // if (layerinfo[lay].channels >= 5) haslayermask = TRUE; } */ } //m_layerDataStartPos = r->GetFilePos(r->file); m_layerDataStartPos = m_file->Seek(0, IO::STREAM_SEEK_CUR); uint32 offset = 0; for (lay = 0; lay < numLayers; lay++) { for (int ch = 0; ch < m_layerList[lay]->layerinfo.channels; ch++) { offset += m_layerList[lay]->channelinfo[ch].length; } } m_file->Seek(offset, IO::STREAM_SEEK_CUR); uint32 layerinfoEndPos = m_file->Seek(0, IO::STREAM_SEEK_CUR); // Align on word if (layerinfoEndPos & 1) { m_file->Seek(1, IO::STREAM_SEEK_CUR); layerinfoEndPos++; } #if 0 if (m_layerinfoLength != (layerinfoEndPos - m_layerinfoStartPos)) { /* sprintf(r->errorMsg, "Layerinfo length is wrong size should be: %d, is: %d, file corrupt?", psdfile->layerinfoLength, layerinfoEndPos-psdfile->layerinfoStartPos); */ //result = -1;//PLUGIN_MSG; throw -1;//return result; } #endif // Global Info uint32 globalinfosize; m_file->Read(&globalinfosize, 4); globalinfosize = BigEndian32(globalinfosize); if (globalinfosize > 0) { if (globalinfosize == sizeof(GLOBALLAYERMASKINFO)) { GLOBALLAYERMASKINFO globallayerinfo; m_file->Read(&globallayerinfo, sizeof(GLOBALLAYERMASKINFO)); globallayerinfo.overlayColorSpace = BigEndian16(globallayerinfo.overlayColorSpace); globallayerinfo.opacity = BigEndian16(globallayerinfo.opacity); TRACE("opacity: %d\n", globallayerinfo.opacity); TRACE("kind: %d\n", globallayerinfo.kind); } else { TRACE("globalinfosize diff %d, %d\n", globalinfosize, sizeof(GLOBALLAYERMASKINFO)); m_file->Seek(globalinfosize, IO::STREAM_SEEK_CUR); } } }
void Linker::Relocate2(int nsection, const char* sectionname, uint8* data, ObjectFileParser* parser, OFile2* pOFile2, OFile* pOFile) { int nrelocs = parser->GetNumberOfRelocations(nsection); for (int i = 0; i < nrelocs; i++) { Relocation* pReloc = parser->GetRelocation(nsection, i); if (pReloc->r_extern) { ObjectSymbol* pSymbol = parser->GetSymbol(pReloc->r_symbolnum); if (!strcmp(pSymbol->n_name, "___dosname")) { TRACE(""); } GlobalSymbol* globsym = globsyms[new StringA(string_copy(pSymbol->n_name))]; if (globsym == NULL) { printf("globsym == NULL\n"); exit(0); } if (globsym->ResolvedValue == 0) { if (/*globsym->defined == 0 &&*/ globsym->Value != 0) // Create a bss entry for it { uint8* bssdata = new uint8[globsym->Value]; memset(bssdata, 0, globsym->Value); globsym->defined = 1; globsym->ResolvedValue = (ULONG)bssdata; } } /* if ((pSymbol->n_type & N_TYPE) == N_SETV) { TRACE("SetV %d\n", pSymbol->n_value); } */ if (!globsym->defined) { printf("%s:%s(.%s+0x%x): undefined reference to %s\n", pOFile2->m_afilename->c_str(), pOFile2->m_ofilename->c_str(), sectionname, pReloc->r_address, pSymbol->n_name); TRACE("%s:%s(.%s+0x%x): undefined reference to %s\n", pOFile2->m_afilename->c_str(), pOFile2->m_ofilename->c_str(), sectionname, pReloc->r_address, pSymbol->n_name); m_undefinedReferenceCount++; continue; } if (globsym->m_pIndirect) { // if (globsym->m_pIndirect->ResolvedValue == 0) { //FileByteStream file(globsym->m_stream); LoadObjectFile2(globsym->m_pIndirect->m_pOFile); } globsym->ResolvedValue = globsym->m_pIndirect->ResolvedValue; } else { if (globsym->m_pOFile) // if (globsym->ResolvedValue == 0) { //FileByteStream file(globsym->m_stream); LoadObjectFile2(globsym->m_pOFile); } } if (globsym->ResolvedValue == 0) { TRACE("warning: unresolved %s\n", globsym->m_name->c_str()); //ASSERT(globsym->ResolvedValue); } /* if (globsym->ResolvedValue == 0) { globsym->m_stream->Seek(0, System::IO::STREAM_SEEK_SET); //FileByteStream file(globsym->m_stream); LoadObjectFile(globsym->m_stream); } */ // if ((pReloc->r_symbolnum & N_TYPE) == N_TEXT) { uint32 oldaddress = BigEndian32(*(uint32*)(data + pReloc->r_address)); uint32* address = (uint32*)(data + pReloc->r_address); *address += globsym->ResolvedValue; } /* else if ((pReloc->r_symbolnum & N_TYPE) == N_DATA) { *(DWORD*)(textdata + pReloc->r_address) = pSymbol->Value; } */ #if 0 gsymmap_t::iterator gsym = l2g[pReloc->r_symbolnum]; if (gsym != NULL) { std::string name = (*gsym).first; /* for (int j = 0; j < m_objfiles.size(); j++) { } */ //*(DWORD*)(textdata + pReloc->r_address) = 0; DWORD _Offset = ftell(fileout) + pReloc->r_address; (*gsym).second->refs.push_back(_Offset); } #endif /* Linker::symbolmap::iterator symboli = symbols.find(pSymbol->n_name); if (symboli == symbols.end()) { printf("Unresolved external symbol '%s'\n", pSymbol->n_name); } */ } else { //ObjectSymbol* pSymbol = pOFile->GetSymbol(pReloc->r_symbolnum); if ((pReloc->r_symbolnum & N_TYPE) == N_TEXT) { *(uint32*)(data + pReloc->r_address) += (long)pOFile->m_textdata;//windowsHeader.ImageBase + pSectionText->VirtualAddress; } else if ((pReloc->r_symbolnum & N_TYPE) == N_DATA) { *(uint32*)(data + pReloc->r_address) += -pOFile->m_textsize + (long)pOFile->m_datadata;//windowsHeader.ImageBase + pSectionData->VirtualAddress; } else if ((pReloc->r_symbolnum & N_TYPE) == N_BSS) { *(uint32*)(data + pReloc->r_address) += -pOFile->m_textsize - pOFile->m_datasize + (long)pOFile->m_bssdata;//windowsHeader.ImageBase + pSectionData->VirtualAddress; } else ASSERT(0); } } }
ErrorCode CMNGDecoder::Open() { ULONG nRead; uint32 value; nRead = m_stream->Read(&value, 4); if (nRead != 4) return Error; if (value != 0x474e4d8a) return Error; nRead = m_stream->Read(&value, 4); if (nRead != 4) return Error; if (value != 0x0a1a0a0d) return Error; while (1) { ULONG length; nRead = m_stream->Read(&length, 4); if (nRead != 4) break; length = BigEndian32(length); uint32 type; nRead = m_stream->Read(&type, 4); type = BigEndian32(type); TRACE("%4.4s %X\n", &type, type); LONGLONG ppos = m_stream->Seek(0, STREAM_SEEK_CUR); switch (type) { case CK_MHDR: { } break; case CK_FRAM: { } break; case CK_IHDR: { if (length != sizeof(m_ihdr)) return Error; nRead = m_stream->Read(&m_ihdr, length); if (nRead != length) return Error; m_ihdr.Width = BigEndian32(m_ihdr.Width); m_ihdr.Height = BigEndian32(m_ihdr.Height); } break; case CK_PLTE: { m_paletteEntry = new Imaging::NGFormat::PaletteEntry[256]; nRead = m_stream->Read(m_paletteEntry, length); if (nRead != length) return Error; } break; case CK_IDAT: { m_idata_length = length; m_idata_offset = 0; /* if (false) { BYTE* source = new BYTE[length]; m_stream->Read(source, length, &nRead); BYTE* dest = new BYTE[length*16]; unsigned long destLen = length*16; uncompress(dest, &destLen, source, length); } */ // return 0; } break; } //li.QuadPart = ppos.QuadPart+length; m_stream->Seek(ppos+length, STREAM_SEEK_SET); uint32 crc; nRead = m_stream->Read(&crc, 4); crc = BigEndian32(crc); /* if (type == CK_IEND) { break; } */ } return Success; }
ErrorCode InitialObjectDescriptor::Read(Stream& stream) { ULONG nRead; uint32 verflags; nRead = stream.Read(&verflags, 4); verflags = BigEndian32(verflags); uint8 version = (uint8)(verflags>>24); BaseDescriptor descr; descr.Descend(stream); if (descr.m_tag == 0x01) // ObjectDescrTag { VERIFY(0); } else if (descr.m_tag == 0x02) // InitialObjectDescrTag { VERIFY(0); } else if (descr.m_tag == 0x10) // MP4_IOD_Tag { // System::IO::CBitStream bitstream(new System::IO::CByteStream(stream)); // System::IO::CBitStream32* pBitStream = &bitstream; uint16 word = ReadByte(stream)<<8; word |= ReadByte(stream); // stream->Read(&word, 2); // word = BigEndian16(word); m_ObjectDescriptorID = word >> 6;//pBitStream->getnbits(10); int bURLFlag = (word>>5) & 1;//pBitStream->getbit();// URL_Flag; int includeInlineProfileLevelFlag = (word>>4) & 1;//pBitStream->getbit(); int reserved = word & 15;//pBitStream->getnbits(4); // reserved=0b1111; ASSERT(reserved == 0xf); if (bURLFlag) { uint8 URLlength; //= pBitStream->getnbits(8);// URLlength; //bit(8) URLstring[URLlength]; ASSERT(0); } else { uint8 ODProfileLevelIndication = ReadByte(stream); uint8 sceneProfileLevelIndication = ReadByte(stream); uint8 audioProfileLevelIndication = ReadByte(stream); uint8 visualProfileLevelIndication = ReadByte(stream); uint8 graphicsProfileLevelIndication = ReadByte(stream); while (descr.More(stream)) { BaseDescriptor descr2; descr2.Descend(stream); if (descr2.m_tag == 0x0E) // ES_ID_IncTag { uint32 Track_ID; stream.Read(&Track_ID, 4);//= pBitStream->getnbits(32); Track_ID = BigEndian32(Track_ID); m_trackID.Add(Track_ID); } else { MessageBeep(-1); } descr2.Ascend(stream); } /* ES_Descriptor esDescr[1 .. 255]; OCI_Descriptor ociDescr[0 .. 255]; IPMP_DescriptorPointer ipmpDescrPtr[0 .. 255]; */ } //ExtensionDescriptor extDescr[0 .. 255]; }
long AOutParser::Read(Stream* stream) { m_pStream = stream; ULONG filesize = stream->GetSize(); if (stream->Read(&exec_header, sizeof(exec)) != sizeof(exec)) { // printf("AOut read error\n"); return -1; } switch (N_GETMAGIC(&exec_header)) { case A_MAGIC: //printf("68020"); break; case I_MAGIC: //printf("intel 386"); break; case J_MAGIC:// printf("intel 960"); break; case K_MAGIC:// printf("sparc"); break; case V_MAGIC:// printf("mips 3000"); break; case X_MAGIC:// printf("att dsp 3210"); break; case M_MAGIC:// printf("mips 4000"); break; case D_MAGIC:// printf("amd 29000"); break; case E_MAGIC:// printf("arm 7-something"); break; case Q_MAGIC:// printf("powerpc"); break; case N_MAGIC:// printf("mips 4000-le"); break; case L_MAGIC:// printf("dec alpha"); break; break; default: // printf("AOut: Unknown magic\n"); return -2; } exec_header.a_text = BigEndian32(exec_header.a_text); exec_header.a_data = BigEndian32(exec_header.a_data); exec_header.a_bss = BigEndian32(exec_header.a_bss); exec_header.a_trsize = BigEndian32(exec_header.a_trsize); exec_header.a_drsize = BigEndian32(exec_header.a_drsize); exec_header.a_syms = BigEndian32(exec_header.a_syms); m_numberOfSections = 0; m_Sections[0] = -1; m_Sections[1] = -1; m_Sections[2] = -1; if (exec_header.a_text) m_Sections[m_numberOfSections++] = 0; if (exec_header.a_data) m_Sections[m_numberOfSections++] = 1; if (exec_header.a_bss) m_Sections[m_numberOfSections++] = 2; m_nsymbols = exec_header.a_syms / sizeof(nlist); #if 0 printf("text size: %d\n", exec_header.a_text); printf("data size: %d\n", exec_header.a_data); printf("bss size: %d\n", exec_header.a_bss); printf("text reloc size: %d\n", exec_header.a_trsize); printf("data reloc size: %d\n", exec_header.a_drsize); printf("symbol size: %d\n", exec_header.a_syms); printf("number of symbols: %d\n", nsymbols); #endif m_TextOffset = sizeof(exec); m_DataOffset = sizeof(exec) + exec_header.a_text; m_TextRelocOffset = m_DataOffset + exec_header.a_data; m_DataRelocOffset = m_TextRelocOffset + exec_header.a_trsize; m_SymbolTableOffset = m_DataRelocOffset + exec_header.a_drsize; m_StringTableOffset = m_SymbolTableOffset + exec_header.a_syms; { int count = exec_header.a_trsize / sizeof(relocation_info); // fprintf(stdout, "nrelocs: %d\n", count); if (count) { stream->Seek(m_TextRelocOffset, System::IO::STREAM_SEEK_SET); m_tr = new Relocation[count]; for (int i = 0; i < count; i++) { relocation_info relocinfo;// = &m_tr[i]; stream->Read(&relocinfo, sizeof(relocation_info)); m_tr[i].r_address = BigEndian32(relocinfo.r_address); // ((DWORD*)&relocinfo)[1] = BigEndian32(((DWORD*)&relocinfo)[1]); // fprintf(stdout, "r_address: %d, ", m_tr[i].r_address); uint8* bf = (uint8*)(((uint32*)&relocinfo)+1); bool r_pcrel = (bf[3] >> 7) & 0x1; int r_length = (bf[3] >> 5) & 0x3; bool r_extern = (bf[3] >> 4) & 0x1; bool r_baserel = (bf[3] >> 3) & 0x1; bool r_jmptable = (bf[3] >> 2) & 0x1; bool r_relative = (bf[3] >> 1) & 0x1; bool r_copy = (bf[3] >> 0) & 0x1; // TODO, support other values on these VERIFY(r_length == 2); VERIFY(r_baserel == 0); VERIFY(r_jmptable == 0); VERIFY(r_relative == 0); VERIFY(r_copy == 0); m_tr[i].r_extern = r_extern; m_tr[i].r_pcrel = r_pcrel; //TRACE("pcrel: %d, baserel: %d, relative: %d, copy: %d\n", r_pcrel, r_baserel, r_relative, r_copy); uint32 symbolnum = (bf[0]<<16) | (bf[1]<<8) | (bf[2]); //printf("symbolnum: %d, r_baserel: %d, r_extern: %d\n", symbolnum, r_baserel, r_extern); // relocinfo->r_symbolnum = symbolnum; // hm.. m_tr[i].r_symbolnum = symbolnum; // fprintf(stdout, "symbolnum: %d", m_tr[i].r_symbolnum); // printf("Text Reloc(addr=%d, symbol=%d)\n", relocinfo->r_address - m_TextOffset, symbolnum); // fprintf(stdout, "\n"); } } } { int count = exec_header.a_drsize / sizeof(relocation_info); // fprintf(stdout, "nrelocs: %d\n", count); if (count) { stream->Seek(m_DataRelocOffset, System::IO::STREAM_SEEK_SET); m_dr = new Relocation[count]; for (int i = 0; i < count; i++) { relocation_info relocinfo;// = &m_tr[i]; stream->Read(&relocinfo, sizeof(relocation_info)); m_dr[i].r_address = BigEndian32(relocinfo.r_address); // ((DWORD*)&relocinfo)[1] = BigEndian32(((DWORD*)&relocinfo)[1]); // fprintf(stdout, "r_address: %d, ", m_tr[i].r_address); uint8* bf = (uint8*)(((uint32*)&relocinfo)+1); bool r_pcrel = (bf[3] >> 7) & 0x1; int r_length = (bf[3] >> 5) & 0x3; bool r_extern = (bf[3] >> 4) & 0x1;; bool r_baserel = (bf[3] >> 3) & 0x1; bool r_jmptable = (bf[3] >> 2) & 0x1; bool r_relative = (bf[3] >> 1) & 0x1; bool r_copy = (bf[3] >> 0) & 0x1; // ASSERT(r_pcrel == 0); ASSERT(r_length == 2); ASSERT(r_baserel == 0); ASSERT(r_jmptable == 0); ASSERT(r_relative == 0); ASSERT(r_copy == 0); m_dr[i].r_extern = r_extern; m_dr[i].r_pcrel = r_pcrel; //TRACE("pcrel: %d, baserel: %d, relative: %d, copy: %d\n", r_pcrel, r_baserel, r_relative, r_copy); uint32 symbolnum = (bf[0]<<16) | (bf[1]<<8) | (bf[2]); //printf("symbolnum: %d, r_baserel: %d, r_extern: %d\n", symbolnum, r_baserel, r_extern); // relocinfo->r_symbolnum = symbolnum; // hm.. m_dr[i].r_symbolnum = symbolnum; // fprintf(stdout, "symbolnum: %d", m_tr[i].r_symbolnum); // printf("Text Reloc(addr=%d, symbol=%d)\n", relocinfo->r_address - m_TextOffset, symbolnum); // fprintf(stdout, "\n"); } } } // Symbols if (m_nsymbols) { m_nlistSymbols = new nlist[m_nsymbols]; long StringTableLen = filesize - m_StringTableOffset; stream->position = m_StringTableOffset; m_StringData = new char[StringTableLen]; int n = stream->Read(m_StringData, StringTableLen); ASSERT(n == StringTableLen); stream->position = m_SymbolTableOffset; for (int i = 0; i < m_nsymbols; i++) { nlist& symbol = m_nlistSymbols[i]; stream->Read(&symbol, sizeof(nlist)); symbol.n_un.n_strx = BigEndian32(symbol.n_un.n_strx); symbol.n_value = BigEndian32(symbol.n_value); symbol.n_desc = BigEndian16(symbol.n_desc); // Convert offset into string table to pointer symbol.n_un.n_name = m_StringData + symbol.n_un.n_strx; if ((symbol.n_type & N_TYPE) == N_DATA) { symbol.n_value -= exec_header.a_text; } /* printf("%d, %s, value=%d, type=%d", i+1, symbol.n_un.n_name, symbol.n_value, symbol.n_type); printf("\n"); */ } } #if 0 { uint8* text = new uint8[exec_header.a_text]; if (text == NULL) { printf("Out of memory"); return -1; } fseek(fp, m_TextOffset, SEEK_SET); fread(text, 1, exec_header.a_text, fp); // Text Code if (N_GETMAGIC(&exec_header) == A_MAGIC) // // 68020 { pass2_CODE(text, exec_header.a_text, m_nsymbols, Symbols); } else if (N_GETMAGIC(&exec_header) == I_MAGIC) // intel 386 { ReadCode_x86(text, exec_header.a_text); } else if (N_GETMAGIC(&exec_header) == Q_MAGIC) // powerpc { dasm_powerpc(text, exec_header.a_text); } else { } delete[] text; } #endif return 0; }