LOCAL bool REISERFS_init(DeviceHandle *deviceHandle, REISERFSHandle *reiserFSHandle) { ReiserSuperBlock reiserSuperBlock; assert(deviceHandle != NULL); assert(reiserFSHandle != NULL); /* read super-block */ if (Device_seek(deviceHandle,REISERFS_SUPER_BLOCK_OFFSET) != ERROR_NONE) { return FALSE; } if (Device_read(deviceHandle,&reiserSuperBlock,sizeof(reiserSuperBlock),NULL) != ERROR_NONE) { return FALSE; } /* check if this a ReiserFS super block */ if ( (strncmp(reiserSuperBlock.magicString,REISERFS_SUPER_MAGIC_STRING_V1,strlen(REISERFS_SUPER_MAGIC_STRING_V1)) != 0) && (strncmp(reiserSuperBlock.magicString,REISERFS_SUPER_MAGIC_STRING_V3,strlen(REISERFS_SUPER_MAGIC_STRING_V2)) != 0) && (strncmp(reiserSuperBlock.magicString,REISERFS_SUPER_MAGIC_STRING_V3,strlen(REISERFS_SUPER_MAGIC_STRING_V3)) != 0) && (strncmp(reiserSuperBlock.magicString,REISERFS_SUPER_MAGIC_STRING_V4,strlen(REISERFS_SUPER_MAGIC_STRING_V4)) != 0) ) { return FALSE; } /* get file system block info */ reiserFSHandle->totalBlocks = LE32_TO_HOST(reiserSuperBlock.blockCount); reiserFSHandle->blockSize = LE32_TO_HOST(reiserSuperBlock.blockSize); reiserFSHandle->bitmapIndex = -1; /* validate data */ if ( !(reiserFSHandle->blockSize >= 512) || !((reiserFSHandle->blockSize % 512) == 0) || !(reiserFSHandle->totalBlocks > 0) ) { return FALSE; } return TRUE; }
struct dc_cal_tbl * dc_cal_tbl_load(uint8_t *buf, size_t buf_len) { struct dc_cal_tbl *ret; uint32_t i; uint16_t magic; if (buf_len < DC_CAL_TBL_MIN_SIZE) { return NULL; } memcpy(&magic, buf, sizeof(magic)); if (LE16_TO_HOST(magic) != DC_CAL_TBL_MAGIC) { log_debug("Invalid magic value in cal table: %d\n", magic); return NULL; } buf += sizeof(magic); ret = malloc(sizeof(ret[0])); if (ret == NULL) { return NULL; } buf += sizeof(uint32_t); /* Skip reserved bytes */ memcpy(&ret->version, buf, sizeof(ret->version)); ret->version = LE32_TO_HOST(ret->version); buf += sizeof(ret->version); memcpy(&ret->n_entries, buf, sizeof(ret->n_entries)); ret->n_entries = LE32_TO_HOST(ret->n_entries); buf += sizeof(ret->n_entries); if (buf_len < (DC_CAL_TBL_META_SIZE + DC_CAL_TBL_ENTRY_SIZE * ret->n_entries) ) { free(ret); return NULL; } ret->entries = malloc(sizeof(ret->entries[0]) * ret->n_entries); if (ret->entries == NULL) { free(ret); return NULL; } ret->reg_vals.lpf_tuning = *buf++; ret->reg_vals.tx_lpf_i = *buf++; ret->reg_vals.tx_lpf_q = *buf++; ret->reg_vals.rx_lpf_i = *buf++; ret->reg_vals.rx_lpf_q = *buf++; ret->reg_vals.dc_ref = *buf++; ret->reg_vals.rxvga2a_i = *buf++; ret->reg_vals.rxvga2a_q = *buf++; ret->reg_vals.rxvga2b_i = *buf++; ret->reg_vals.rxvga2b_q = *buf++; ret->curr_idx = ret->n_entries / 2; for (i = 0; i < ret->n_entries; i++) { memcpy(&ret->entries[i].freq, buf, sizeof(uint32_t)); buf += sizeof(uint32_t); memcpy(&ret->entries[i].dc_i, buf, sizeof(int16_t)); buf += sizeof(int16_t); memcpy(&ret->entries[i].dc_q, buf, sizeof(int16_t)); buf += sizeof(int16_t); ret->entries[i].freq = LE32_TO_HOST(ret->entries[i].freq); ret->entries[i].dc_i = LE32_TO_HOST(ret->entries[i].dc_i); ret->entries[i].dc_q = LE32_TO_HOST(ret->entries[i].dc_q); } return ret; }
/* Called when a read completes. IHXBuffer contains the data read */ STDMETHODIMP CAVIIndex::RIFFReadDone(HX_RESULT status, IHXBuffer *pBuffer) { //HX_TRACE("CAVIFileFormat::CAVIIndex::RIFFReadDone()\n"); HX_ASSERT(m_state == eReadSlice); if (m_bDiscardPendingIO) { // We've seeked or the stream has ended since the I/O request; // let the the outer object reschedule disk reads. m_bDiscardPendingIO = FALSE; m_state = eReady; m_pOuter->IOEvent(); return HXR_OK; } // We should never have a failed read unless the file is truncated: if (FAILED(status) || !(pBuffer->GetSize() / sizeof(idx1Entry))) { // Adjust index size: m_ulIndexLength = m_pReader->GetOffset() - m_ulIndexOffset; switch (m_scanState) { case eInitial: m_scanState = ePreroll; m_state = eSeekToRecord; m_pReader->FileSeek(m_ulIndexOffset); break; case ePreroll: m_scanState = eComplete; break; case eComplete: default: break; // TODO: Add correct event callback } } else { idx1Entry* pEntry = (idx1Entry*) pBuffer->GetBuffer(); HX_ASSERT(pEntry); switch (m_scanState) { case eInitial: { HX_ASSERT(pBuffer->GetSize() / sizeof(idx1Entry)); for (UINT32 i = 0; i < pBuffer->GetSize() / sizeof(idx1Entry); ++i) { if (CAVIFileFormat::IsAVChunk(pEntry->ulChunkId)) { StreamSlice* pStream = (StreamSlice*) m_sliceArray[CAVIFileFormat::GetStream(pEntry->ulChunkId)]; pStream->ulTotalBytes += LE32_TO_HOST(pEntry->ulChunkLength); if (pEntry->ulChunkLength > pStream->ulMaxChunkSize) { pStream->ulMaxChunkSize = LE32_TO_HOST(pEntry->ulChunkLength); } pStream->ulTotalChunks++; } pEntry++; } HX_ASSERT((INT64) m_ulIndexOffset + m_ulIndexLength - m_pReader->GetOffset() >= 0); UINT32 ulIndexRemaining = m_ulIndexOffset + m_ulIndexLength - m_pReader->GetOffset(); ulIndexRemaining -= ulIndexRemaining % sizeof(idx1Entry); if (ulIndexRemaining >= sizeof(idx1Entry)) { m_state = eReadSlice; m_pReader->Read((ulIndexRemaining > LOAD_GRANULARITY*sizeof(idx1Entry)) ? LOAD_GRANULARITY*sizeof(idx1Entry) : ulIndexRemaining); } else { // Truncated files not supported, for now: HX_ASSERT(m_pReader->GetOffset() == m_ulIndexOffset + m_ulIndexLength); m_state = eSeekToRecord; m_scanState = ePreroll; m_pReader->FileSeek(m_ulIndexOffset); } break; } case ePreroll: { HX_ASSERT(pBuffer->GetSize() / sizeof(idx1Entry)); for (UINT32 i = 0; i < pBuffer->GetSize() / sizeof(idx1Entry); ++i) { if (CAVIFileFormat::IsAVChunk(pEntry->ulChunkId)) { StreamSlice* pStream = (StreamSlice*) m_sliceArray[CAVIFileFormat::GetStream(pEntry->ulChunkId)]; UINT32 ulAverageBytesPerChunk = (UINT32) (pStream->ulTotalBytes / (double) pStream->ulTotalChunks); pStream->llByteDeflict -= ((INT64) ulAverageBytesPerChunk - LE32_TO_HOST(pEntry->ulChunkLength)); // Check max: if (pStream->llByteDeflict > pStream->ulPrerollBytes) { HX_ASSERT(pStream->llByteDeflict < MAX_UINT32); pStream->ulPrerollBytes = (UINT32) pStream->llByteDeflict; } } pEntry++; } HX_ASSERT((INT64) m_ulIndexOffset + m_ulIndexLength - m_pReader->GetOffset() >= 0); UINT32 ulIndexRemaining = m_ulIndexOffset + m_ulIndexLength - m_pReader->GetOffset(); ulIndexRemaining -= ulIndexRemaining % sizeof(idx1Entry); if (ulIndexRemaining >= sizeof(idx1Entry)) { m_state = eReadSlice; m_pReader->Read((ulIndexRemaining > LOAD_GRANULARITY*sizeof(idx1Entry)) ? LOAD_GRANULARITY*sizeof(idx1Entry) : ulIndexRemaining); } else { HX_ASSERT(m_pReader->GetOffset() == m_ulIndexOffset + m_ulIndexLength); //m_state = eReady; m_state = eSeekToRecord; m_scanState = eComplete; //m_pOuter->IOEvent(); m_pReader->FileSeek(m_ulIndexOffset); } break; // In the future, we may consider reading the index data, too; // the current case is optimized for large files (MAX_SLICE_SIZE < chunks in file) } default: case eComplete: { for (UINT32 i = pBuffer->GetSize() / sizeof(idx1Entry); i > 0; --i) { if (!m_bRelativeIndexDetermined) { if (LE32_TO_HOST(pEntry->ulChunkOffset) == m_ulFirstMOVIOffset + 4) { // Offsets are not relative to the movi chunk: m_ulFirstRelativeMOVIOffset = 0; } m_bRelativeIndexDetermined = TRUE; } if (CAVIFileFormat::IsAVChunk(pEntry->ulChunkId)) { StreamSlice* pStream = (StreamSlice*) m_sliceArray[CAVIFileFormat::GetStream(pEntry->ulChunkId)]; if ((INT64) pStream->ulSliceEndChunk - pStream->ulNextChunkRequired < MAX_SLICE_SIZE) { pStream->bSliceOffsetCapped = FALSE; if (pStream->ulSliceEndChunk - pStream->ulSliceStartChunk == MAX_SLICE_SIZE) { if (pStream->entryArray[pStream->ulSliceStartChunk % MAX_SLICE_SIZE].bKeyChunk) { pStream->ulLastKeyChunk = pStream->ulSliceStartChunk; pStream->ulLastKeyChunkOffset = pStream->entryArray[pStream->ulSliceStartChunk % MAX_SLICE_SIZE].ulOffset; } pStream->ulSliceStartChunk++; HX_ASSERT(pStream->ulSliceStartChunk <= pStream->ulNextChunkRequired); } if(LE32_TO_HOST(pEntry->dwFlags) & AVI_IFLAG_KEYCHUNK) { pStream->entryArray[pStream->ulSliceEndChunk % MAX_SLICE_SIZE].bKeyChunk = TRUE; } else { pStream->entryArray[pStream->ulSliceEndChunk % MAX_SLICE_SIZE].bKeyChunk = FALSE; } pStream->entryArray[pStream->ulSliceEndChunk % MAX_SLICE_SIZE].ulOffset = LE32_TO_HOST(pEntry->ulChunkOffset) + m_ulFirstRelativeMOVIOffset; pStream->entryArray[pStream->ulSliceEndChunk % MAX_SLICE_SIZE].ulLength = LE32_TO_HOST(pEntry->ulChunkLength); //HX_TRACE("CAVIIndex::RIFFReadDone stream: %d\toffset: %lu\n", CAVIFileFormat::GetStream(pEntry->ulChunkId), // pStream->entryArray[pStream->ulSliceEndChunk % MAX_SLICE_SIZE].ulOffset); #ifdef _DEBUG_KEYCHUNKS if (pStream->entryArray[pStream->ulSliceEndChunk % MAX_SLICE_SIZE].bKeyChunk) { //HX_TRACE("CAVIIndex::RIFFReadDone keytype: %c%c%c%c\n", pEntry->ulChunkId, pEntry->ulChunkId >> 8, pEntry->ulChunkId >> 16, pEntry->ulChunkId >> 24); } #endif pStream->ulSliceEndChunk++; } else if (!pStream->bSliceOffsetCapped) { pStream->bSliceOffsetCapped = TRUE; pStream->ulSliceEndOffset = m_pReader->GetOffset() - i*sizeof(idx1Entry); } for (UINT16 j = 0; j < m_usStreamCount; j++) { StreamSlice* pStream = (StreamSlice*) m_sliceArray[j]; if (!pStream->bSliceOffsetCapped) { pStream->ulSliceEndOffset = m_pReader->GetOffset() - (i-1)*sizeof(idx1Entry); } } } pEntry++; }
LOCAL FileSystemTypes EXT_init(DeviceHandle *deviceHandle, EXTHandle *extHandle) { EXTSuperBlock extSuperBlock; EXT23GroupDescriptor ext23GroupDescriptor; EXT4GroupDescriptor ext4GroupDescriptor; uint32 z; assert(deviceHandle != NULL); assert(extHandle != NULL); assert(sizeof(extSuperBlock) == 1024); assert(sizeof(ext23GroupDescriptor) == 32); assert(sizeof(ext4GroupDescriptor) == 64); // read first super-block if (Device_seek(deviceHandle,EXT2_FIRST_SUPER_BLOCK_OFFSET) != ERROR_NONE) { return FILE_SYSTEM_TYPE_UNKNOWN; } if (Device_read(deviceHandle,&extSuperBlock,sizeof(extSuperBlock),NULL) != ERROR_NONE) { return FILE_SYSTEM_TYPE_UNKNOWN; } // check if this a super block if ((uint16)(LE16_TO_HOST(extSuperBlock.magic)) != EXT2_SUPER_MAGIC) { return FILE_SYSTEM_TYPE_UNKNOWN; } // get block size switch (LE32_TO_HOST(extSuperBlock.logBlockSize)) { case 0: extHandle->blockSize = 1*1024; break; case 1: extHandle->blockSize = 2*1024; break; case 2: extHandle->blockSize = 4*1024; break; case 3: extHandle->blockSize = 8*1024; break; case 4: extHandle->blockSize = 16*1024; break; case 5: extHandle->blockSize = 32*1024; break; case 6: extHandle->blockSize = 64*1024; break; default: return FILE_SYSTEM_TYPE_UNKNOWN; break; } // get ext type: ext2/3/4 #if 0 #warning debug only fprintf(stderr,"%s, %d: revisionLevel = %d\n",__FILE__,__LINE__,LE32_TO_HOST(extSuperBlock.revisionLevel)); fprintf(stderr,"%s, %d: featureCompatible = 0x%x\n",__FILE__,__LINE__,LE32_TO_HOST(extSuperBlock.featureCompatible)); fprintf(stderr,"%s, %d: featureInCompatible = 0x%x\n",__FILE__,__LINE__,LE32_TO_HOST(extSuperBlock.featureInCompatible)); fprintf(stderr,"%s, %d: featureCompatible & ~EXT2_FEATURE_COMPAT_SUPP = 0x%x\n",__FILE__,__LINE__,LE32_TO_HOST(extSuperBlock.featureCompatible)& ~EXT2_FEATURE_COMPAT_SUPP); fprintf(stderr,"%s, %d: featureCompatible & ~EXT3_FEATURE_COMPAT_SUPP = 0x%x\n",__FILE__,__LINE__,LE32_TO_HOST(extSuperBlock.featureCompatible)& ~EXT3_FEATURE_COMPAT_SUPP); fprintf(stderr,"%s, %d: featureCompatible & ~EXT4_FEATURE_COMPAT_SUPP = 0x%x\n",__FILE__,__LINE__,LE32_TO_HOST(extSuperBlock.featureCompatible)& ~EXT4_FEATURE_COMPAT_SUPP); fprintf(stderr,"%s, %d: featureInCompatible & ~EXT2_FEATURE_INCOMPAT_SUPP = 0x%x\n",__FILE__,__LINE__,LE32_TO_HOST(extSuperBlock.featureInCompatible)& ~EXT2_FEATURE_INCOMPAT_SUPP); fprintf(stderr,"%s, %d: featureInCompatible & ~EXT3_FEATURE_INCOMPAT_SUPP = 0x%x\n",__FILE__,__LINE__,LE32_TO_HOST(extSuperBlock.featureInCompatible)& ~EXT3_FEATURE_INCOMPAT_SUPP); fprintf(stderr,"%s, %d: featureInCompatible & ~EXT4_FEATURE_INCOMPAT_SUPP = 0x%x\n",__FILE__,__LINE__,LE32_TO_HOST(extSuperBlock.featureInCompatible)& ~EXT4_FEATURE_INCOMPAT_SUPP); #endif /* 0 */ if ( ((LE32_TO_HOST(extSuperBlock.featureCompatible ) & ~EXT2_FEATURE_COMPAT_SUPP ) == 0) && ((LE32_TO_HOST(extSuperBlock.featureInCompatible) & ~EXT2_FEATURE_INCOMPAT_SUPP) == 0) ) { // ext2 extHandle->type = FILE_SYSTEM_TYPE_EXT2; } else if ( (LE32_TO_HOST(extSuperBlock.revisionLevel) == EXT2_REVISION_DYNAMIC) && ((LE32_TO_HOST(extSuperBlock.featureCompatible ) & ~EXT3_FEATURE_COMPAT_SUPP ) == 0) && ((LE32_TO_HOST(extSuperBlock.featureInCompatible) & ~EXT3_FEATURE_INCOMPAT_SUPP) == 0) ) { // ext3 extHandle->type = FILE_SYSTEM_TYPE_EXT3; } else if ( (LE32_TO_HOST(extSuperBlock.revisionLevel) == EXT2_REVISION_DYNAMIC) && ((LE32_TO_HOST(extSuperBlock.featureCompatible ) & ~EXT4_FEATURE_COMPAT_SUPP ) == 0) && ((LE32_TO_HOST(extSuperBlock.featureInCompatible) & ~EXT4_FEATURE_INCOMPAT_SUPP) == 0) ) { // ext4 extHandle->type = FILE_SYSTEM_TYPE_EXT4; } else { return FILE_SYSTEM_TYPE_UNKNOWN; } // get file system block info, init data switch (extHandle->type) { case FILE_SYSTEM_TYPE_EXT2: case FILE_SYSTEM_TYPE_EXT3: extHandle->groupDescriptorSize = sizeof(EXT23GroupDescriptor); extHandle->blocksPerGroup = LE32_TO_HOST(extSuperBlock.blocksPerGroup); extHandle->firstDataBlock = (uint64)LE32_TO_HOST(extSuperBlock.firstDataBlock); extHandle->totalBlocks = (uint64)LE32_TO_HOST(extSuperBlock.blocksCount); break; case FILE_SYSTEM_TYPE_EXT4: extHandle->groupDescriptorSize = //((LE32_TO_HOST(extSuperBlock.featureCompatible ) & EXT4_FEATURE_COMPAT_HAS_JOURNAL) != 0) ((LE32_TO_HOST(extSuperBlock.featureInCompatible) & EXT4_FEATURE_INCOMPAT_64BIT) != 0) ? (uint)LE16_TO_HOST(extSuperBlock.groupDescriptorSize) : sizeof(EXT23GroupDescriptor); extHandle->blocksPerGroup = LE32_TO_HOST(extSuperBlock.blocksPerGroup); extHandle->firstDataBlock = (uint64)LE32_TO_HOST(extSuperBlock.firstDataBlock); extHandle->totalBlocks = LOW_HIGH_TO_UINT64(LE32_TO_HOST(extSuperBlock.blocksCount), LE32_TO_HOST(extSuperBlock.blocksCountHigh) ); break; default: #ifndef NDEBUG HALT_INTERNAL_ERROR_UNHANDLED_SWITCH_CASE(); #endif /* NDEBUG */ break; /* not reached */ } extHandle->bitmapIndex = -1; // validate data if ( !((extHandle->groupDescriptorSize > 0) && (extHandle->groupDescriptorSize <= EXT4_MAX_GROUP_DESCRIPTOR_SIZE)) || !(extHandle->blocksPerGroup > 0) || !(extHandle->totalBlocks > 0) || !( ((extHandle->blockSize <= 1024) && (extHandle->firstDataBlock == 1)) || ((extHandle->blockSize > 1024) && (extHandle->firstDataBlock == 0)) ) ) { return FILE_SYSTEM_TYPE_UNKNOWN; } // read group descriptors and detect bitmap block numbers extHandle->bitmapBlocksCount = (extHandle->totalBlocks+extHandle->blocksPerGroup-1)/extHandle->blocksPerGroup;; extHandle->bitmapBlocks = (uint64*)malloc(extHandle->bitmapBlocksCount*sizeof(uint64)); if (extHandle->bitmapBlocks == NULL) { return FILE_SYSTEM_TYPE_UNKNOWN; } for (z = 0; z < extHandle->bitmapBlocksCount; z++) { if (Device_seek(deviceHandle,EXT_BLOCK_TO_OFFSET(extHandle,extHandle->firstDataBlock+1)+(uint64)z*(uint64)extHandle->groupDescriptorSize) != ERROR_NONE) { free(extHandle->bitmapBlocks); return FILE_SYSTEM_TYPE_UNKNOWN; } switch (extHandle->type) { case FILE_SYSTEM_TYPE_EXT2: case FILE_SYSTEM_TYPE_EXT3: if (Device_read(deviceHandle,&ext23GroupDescriptor,sizeof(ext23GroupDescriptor),NULL) != ERROR_NONE) { free(extHandle->bitmapBlocks); return FILE_SYSTEM_TYPE_UNKNOWN; } extHandle->bitmapBlocks[z] = (uint64)LE32_TO_HOST(ext23GroupDescriptor.blockBitmap); break; case FILE_SYSTEM_TYPE_EXT4: if (Device_read(deviceHandle,&ext4GroupDescriptor,sizeof(ext4GroupDescriptor),NULL) != ERROR_NONE) { free(extHandle->bitmapBlocks); return FILE_SYSTEM_TYPE_UNKNOWN; } extHandle->bitmapBlocks[z] = LOW_HIGH_TO_UINT64(LE32_TO_HOST(ext4GroupDescriptor.blockBitmap), LE32_TO_HOST(ext4GroupDescriptor.blockBitmapHigh) ); break; default: #ifndef NDEBUG HALT_INTERNAL_ERROR_UNHANDLED_SWITCH_CASE(); #endif /* NDEBUG */ break; /* not reached */ } } #if 0 #warning debug only fprintf(stderr,"\n"); for (z = 0; z < extHandle->bitmapBlocksCount; z++) { fprintf(stderr,"%s,%d: z=%d block=%ld used=%d\n",__FILE__,__LINE__,z,extHandle->bitmapBlocks[z],EXT_blockIsUsed(deviceHandle,extHandle,extHandle->bitmapBlocks[z])); } #endif /* 0 */ return extHandle->type; }