int return_filesize(int inode_index){ int num_pointers = get_num_pointers_inode(inode_index); if(num_pointers>NUMBER_INODES-1){ num_pointers--; //check if indirect pointer used,if yes,removed } int array_blockptr[num_pointers]; get_pointers(inode_index,array_blockptr,num_pointers);//copy all pointers except indirect pointer into an array of block pointers int num_full_block=num_pointers-1; //except last block because it might not full //check data in last unfull block int last_block_data=0; char buffer[BLOCKSIZE]; memset(buffer,0,BLOCKSIZE); read_blocks(array_blockptr[num_pointers-1],1, buffer); //read it into memory int a = BLOCKSIZE-1; while(buffer[a]==0){ a--; } last_block_data = a+1; return num_full_block*BLOCKSIZE + last_block_data; }
int32_t cir_storage_flash_init(cir_storage_flash_t *storage) { pointers_block_t local_pointers; if (storage->parent.size%storage->block_size != 0) { return -1; } if (storage->read(storage->address_start, sizeof(pointers_block_t), (uint8_t *)&local_pointers) != 0) { return -1; } /* If an init as already been done */ if (local_pointers.data_pointer_read != 0xFFFFFFFF) { /* Initialize pointers with previous value */ if (get_pointers(storage, &storage->pointers) != 0){ return -1; } return 0; } /* Storage first init */ READ_PTR(storage) = storage->address_start + storage->block_size; WRITE_PTR(storage) = READ_PTR(storage); storage->pointers_index = storage->address_start; /* Erase the two firsts blocks (pointers block and first data block) */ if (storage->erase(storage->block_start, 2) != 0) { return -1; } /* Store our pointers at the beginning of the first block */ return storage->write(storage->address_start, sizeof(pointers_block_t), (uint8_t *)&storage->pointers); }
int main( int nArgs, const char * const args[] ) { if( nArgs != 2 ) { printf("%s: <image>\n", args[0] ); return 1; } const char * infile = args[1]; std::vector<uint8_t> fbuf; { std::ifstream f( infile, std::ios::binary | std::ios::ate ); if( !f.is_open() ) { printf("Unable to open %s\n",infile); return 2; } fbuf.resize( f.tellg() ); f.seekg(0); f.read( (char*)&fbuf[0], fbuf.size() ); if( f.gcount() != fbuf.size() ) { printf("Unable to fully read %s\n",infile); return 3; } } printf( "Scanning binary for strings...\n" ); stable str_table = get_strings( fbuf ); printf( "Total strings found: %d\n", str_table.size() ); printf( "Scanning binary for pointers...\n" ); ptable ptr_table = get_pointers( fbuf ); printf( "Total pointers found: %d\n", ptr_table.size() ); // signal.signal(signal.SIGINT, high_scores) MutexType mutex; //protects next few variables unsigned top_score = 0; scorecard scores; #ifdef _OPENMP #pragma omp parallel for #endif for( offset_t base = 0; base < 0xf0000000UL; base += 0x1000 ) { #ifndef _OPENMP //Turn off status display when using OpenMP //otherwise the numbers will be scrabled if( base % 0x10000 == 0 ) printf( "Trying base address 0x%x\n", base ); #endif unsigned score = 0; for(ptable::iterator iter = ptr_table.begin(); iter != ptr_table.end(); ++iter) { offset_t ptr = iter->first; if( ptr < base ) continue; if( ptr >= (base + fbuf.size()) ) continue; unsigned offset = ptr - base; if( str_table.find(offset) != str_table.end() ) score += iter->second; } if( score ) { mutex.Lock(); scores.push_back( std::make_pair( score, base ) ); if( score > top_score ) { top_score = score; printf( "New highest score, 0x%x: %d\n", base, score ); } mutex.Unlock(); } } std::sort(scores.begin(),scores.end() ); high_scores( scores ); }
int sfs_remove(char *file){ int i; for(i=0;i<TOTAL_NUM_FILES;i++){ if(strncmp(dir_table[i].filename, file, MAXFILENAME)==0){//find the file to be removed in directory table //clear data int inode_index = dir_table[i].inode_number; int num_pointers_in_inode = get_num_pointers_inode(inode_index); int indirect_pointer = 0; if(num_pointers_in_inode>=INODE_POINTERS){ //get the indirect block address indirect_pointer = inodes[inode_index].pointers[INODE_POINTERS-1]; //and remove it from number of pointers num_pointers_in_inode--; } int array_blockptr[num_pointers_in_inode]; get_pointers(inode_index, array_blockptr,num_pointers_in_inode);//get all pointers in array_blockptr //remove indirect pointer if(indirect_pointer){ char buffer[BLOCKSIZE];//write a empty buffer into disk to overwrite indirect_pointer memset(buffer,0,BLOCKSIZE); write_blocks(indirect_pointer,1,buffer); set_freeblock(indirect_pointer);//set it free again } //handle other pointers //reset the inode INODE free_inode={ .mode=0, .link_cnt=0, .uid=0, .gid=0, .size=0, .pointers={0,0,0,0,0,0,0,0,0,0,0,0,0} //set all the pointers to 0 }; int n; char empty_block_buf[BLOCKSIZE]; for(n=0; n < num_pointers_in_inode; n++){ memset(empty_block_buf,0,BLOCKSIZE); write_blocks(array_blockptr[n],1,empty_block_buf); set_freeblock(array_blockptr[n]); } inodes[inode_index] = free_inode; write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap); //update the free_bitmap //write the updated inode in disk int inode_number = inode_index; int block_of_inode=inode_number/8+1; char update_inode_buffer[BLOCKSIZE]; memset(update_inode_buffer,0, BLOCKSIZE); read_blocks(block_of_inode, 1, update_inode_buffer); memcpy((void *)update_inode_buffer+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE)); write_blocks(block_of_inode, 1, update_inode_buffer); //set information in directory table to 0 memset(dir_table[i].filename,0,MAXFILENAME); dir_table[i].inode_number=0; //update this information into disk char dir_entry_buffer[BLOCKSIZE]; int block_dir_entry=i/NUM_ENTRIES_PERBLOCK+8+1; memset(dir_entry_buffer,0, BLOCKSIZE); read_blocks(block_dir_entry, 1, dir_entry_buffer); memcpy((void *)dir_entry_buffer+(i%21)*sizeof(dir_entry),(const void *) &dir_table[i], sizeof(dir_entry)); write_blocks(block_dir_entry,1,dir_entry_buffer); //clear file descriptor table file_des_t[inode_index-1].open=0; file_des_t[inode_index-1].rw_pointer=0; return 0; } } //files does not exist, return -1 return -1; }
int sfs_fread(int fileID, char *buf, int length){ int num_bytes = 0; int num_pointers = 0; int inode_index = dir_table[fileID].inode_number; if(file_des_t[fileID].open==0){ //check if file is opened return -1; } if(length>inodes[inode_index].size){ length=inodes[inode_index].size; //attempt to read more data than the file has } num_pointers = get_num_pointers_inode(inode_index); if(num_pointers>INODE_POINTERS-1){ num_pointers--; } int array_blockptr[num_pointers]; get_pointers(inode_index,array_blockptr,num_pointers);//get pointers in inode into array_blockptr //find the number of blocks to read int rw_offset = file_des_t[fileID].rw_pointer % BLOCKSIZE; int rw_index = file_des_t[fileID].rw_pointer / BLOCKSIZE + 1; int num_blocks; if(length<(BLOCKSIZE-rw_offset)){ //read within one block char read_buf[BLOCKSIZE]; memset(read_buf,0,BLOCKSIZE); read_blocks(array_blockptr[rw_index-1],1,read_buf); memcpy(buf,read_buf+rw_offset,length); file_des_t[fileID].rw_pointer+=length; return length; } else{ num_blocks=(length-(BLOCKSIZE-rw_offset))/BLOCKSIZE+2; //+2 for the first and last partial block } int k; char read_buf[BLOCKSIZE]; for(k=rw_index-1;k<rw_index+num_blocks-1;k++){ memset(read_buf,0,BLOCKSIZE); read_blocks(array_blockptr[k],1,read_buf); if(k==rw_index-1){ //first is partial block memcpy(buf,read_buf+rw_offset,BLOCKSIZE-rw_offset); //read only the remaining data num_bytes = num_bytes + (BLOCKSIZE-rw_offset); } else if(k==rw_index+num_blocks-2){ //last block is partial block memcpy(buf+num_bytes, read_buf, (length-(BLOCKSIZE-rw_offset))%BLOCKSIZE); num_bytes = num_bytes + (length-(BLOCKSIZE-rw_offset))%BLOCKSIZE; } else{ //full block memcpy(buf+num_bytes, read_buf, BLOCKSIZE); num_bytes = num_bytes + BLOCKSIZE; } } file_des_t[fileID].rw_pointer = file_des_t[fileID].rw_pointer + num_bytes; return num_bytes; }
int sfs_fwrite(int fileID, const char *buf, int length){ int inode_index = dir_table[fileID].inode_number; int num_bytes_to_be_written=0; //index of rw pointers which points to the current block of inode int rw_index = file_des_t[fileID].rw_pointer/BLOCKSIZE+1; //rw pointer offset within its current block int rw_offset = file_des_t[fileID].rw_pointer%BLOCKSIZE; //calculate number of blocks to be written int num_blocks; if(length<BLOCKSIZE-rw_offset){ num_blocks=1; } else{ num_blocks=(length-(BLOCKSIZE-rw_offset))/BLOCKSIZE+2; //+2 for the first & last partial blocks } //writing to an empty file. if(inodes[inode_index].pointers[0]==0){ //If file is empty all inode pointers will be zero int num_bytes_to_be_written = 0; int inode_index=dir_table[fileID].inode_number; int num_blocks=length/(BLOCKSIZE)+1; if(num_blocks<=(INODE_POINTERS-1)){ //don't need the indirect pointer int j; char write_block_buffer[BLOCKSIZE]; for(j=0;j<num_blocks-1;j++){ //reset buffer memset(write_block_buffer,0,BLOCKSIZE); memcpy(write_block_buffer,buf,BLOCKSIZE); inodes[inode_index].pointers[j]=findfreeblock(); int flag = write_blocks(inodes[inode_index].pointers[j],1,write_block_buffer); if(flag){ //if write into disk successfully,count the number of bytes written num_bytes_to_be_written = num_bytes_to_be_written + BLOCKSIZE; } //upodate the bitmap markfreeblock(inodes[inode_index].pointers[j]); } //last block could be a partial block char direct_pointer_buf_last[BLOCKSIZE]; memset(direct_pointer_buf_last,0,BLOCKSIZE); memcpy(direct_pointer_buf_last, buf+(num_blocks-1)*BLOCKSIZE, length % BLOCKSIZE); //find a free block for the last direct pointer int last_direct_pointer = findfreeblock(); markfreeblock(last_direct_pointer); inodes[inode_index].pointers[num_blocks-1] = last_direct_pointer; //if write into disk successfully then count the number of bytes int flag = write_blocks(last_direct_pointer,1,direct_pointer_buf_last); if(flag){ num_bytes_to_be_written = num_bytes_to_be_written + length%BLOCKSIZE; } //update the information in file descriptor table file_des_t[fileID].rw_pointer = file_des_t[fileID].rw_pointer + length; inodes[inode_index].size = inodes[inode_index].size + num_bytes_to_be_written; //update info on the disk int inode_number = inode_index; int block_of_inode=inode_number/8+1; char inode_update_buf[BLOCKSIZE]; memset(inode_update_buf,0, BLOCKSIZE); read_blocks(block_of_inode, 1, inode_update_buf); memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE)); write_blocks(block_of_inode, 1, inode_update_buf); write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap); return num_bytes_to_be_written; } else{ //else need the indirect pointer int m; char write_block_buffer[BLOCKSIZE]; //handle all the direct pointer firstly,similar as the above for(m=0;m<INODE_POINTERS-1;m++){ memset(write_block_buffer,0,BLOCKSIZE); memcpy(write_block_buffer,buf,BLOCKSIZE); inodes[inode_index].pointers[m]=findfreeblock(); int flag=write_blocks(inodes[inode_index].pointers[m],1,write_block_buffer); if(flag){num_bytes_to_be_written+=BLOCKSIZE;} markfreeblock(inodes[inode_index].pointers[m]); } //now let's handle the indirect pointer int num_indirect_pointers = num_blocks-(INODE_POINTERS-1); //get free blocks for indirect pointer int freeblock_indirect = findfreeblock(); markfreeblock(freeblock_indirect); int arr_of_indirectptr[num_indirect_pointers]; int k; //write the remaining data to the indirect blocks char indirect_pointer_buf[BLOCKSIZE]; for(k=0;k<num_indirect_pointers-1;k++){ arr_of_indirectptr[k] = findfreeblock(); memset(indirect_pointer_buf,0,BLOCKSIZE); memcpy(indirect_pointer_buf, buf+(INODE_POINTERS-1)*BLOCKSIZE + k*BLOCKSIZE, BLOCKSIZE); int flag=write_blocks(arr_of_indirectptr[k],1,indirect_pointer_buf); if(flag){num_bytes_to_be_written+=BLOCKSIZE;} markfreeblock(arr_of_indirectptr[k]); } //handle partial indirect block int last_indirect_pointers = findfreeblock(); arr_of_indirectptr[num_indirect_pointers-1] = last_indirect_pointers; markfreeblock(last_indirect_pointers); char last_indirect_pointer_buf[BLOCKSIZE]; memset(last_indirect_pointer_buf,0,BLOCKSIZE); memcpy(last_indirect_pointer_buf,buf+(INODE_POINTERS-1)*BLOCKSIZE+(num_indirect_pointers-1)*BLOCKSIZE,length%BLOCKSIZE); int flag = write_blocks(arr_of_indirectptr[num_indirect_pointers-1],1,last_indirect_pointer_buf); if(flag){ num_bytes_to_be_written = num_bytes_to_be_written + length%BLOCKSIZE; } //Write the indirect pointers to the indirect block char indirect_buffer[BLOCKSIZE]; memset(indirect_buffer,0,BLOCKSIZE); memcpy(indirect_buffer,arr_of_indirectptr,num_indirect_pointers*sizeof(int)); write_blocks(freeblock_indirect,1,indirect_buffer); inodes[inode_index].pointers[INODE_POINTERS-1]=freeblock_indirect; file_des_t[fileID].rw_pointer = file_des_t[fileID].rw_pointer + length; inodes[inode_index].size = inodes[inode_index].size + num_bytes_to_be_written; //update all the info into the disk int inode_number = inode_index; int block_of_inode = inode_number/8+1; char inode_update_buf[BLOCKSIZE]; memset(inode_update_buf,0, BLOCKSIZE); read_blocks(block_of_inode, 1, inode_update_buf); memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE)); write_blocks(block_of_inode, 1, inode_update_buf); write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap); return num_bytes_to_be_written; } } //file not empty int number_pointers; if(get_num_pointers_inode(inode_index)>INODE_POINTERS-1){ //first ignore the indrect pointers if it is used number_pointers = get_num_pointers_inode(inode_index)-1; } else{ number_pointers = get_num_pointers_inode(inode_index); } int array_blockptr[number_pointers]; get_pointers(inode_index,array_blockptr,number_pointers); int num_unchanged_blocks = rw_index; //Update all those blocks int updated_array_blockptr[num_blocks + num_unchanged_blocks]; memset(updated_array_blockptr,0,num_blocks*sizeof(int)); //Copy the unchanged blocks int p; for(p = 0; p < rw_index-1; p++){ updated_array_blockptr[p] = array_blockptr[p]; } int s; for(s=rw_index-1; s<((num_blocks+num_unchanged_blocks)-1); s++){ //Allocate additional free blocks when s>total intial blocks if(s>number_pointers-1){ //free block is not enough, find more if(s==(num_blocks+num_unchanged_blocks-2)){ //last block need to do a partial write int free_block = findfreeblock(); updated_array_blockptr[s] = free_block; markfreeblock(free_block); if(num_blocks==1){ update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,length); num_bytes_to_be_written=num_bytes_to_be_written+length; } else{ if((BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index)<0){ return -1;//write in last block } update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index)),0,(length-(BLOCKSIZE-rw_offset))%BLOCKSIZE); num_bytes_to_be_written = num_bytes_to_be_written + (length-(BLOCKSIZE-rw_offset)) % BLOCKSIZE; } } else{ int free_block = findfreeblock(); updated_array_blockptr[s] = free_block; markfreeblock(free_block); update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index)),0,BLOCKSIZE); num_bytes_to_be_written = num_bytes_to_be_written + BLOCKSIZE; } } else{ markfreeblock(array_blockptr[s]); updated_array_blockptr[s] = array_blockptr[s]; if(s==rw_index-1){ //Overwriting the first block of write if(num_blocks==1){ //if only updating one block - will not be filling the first block of the write. update_block(array_blockptr[s],(char*)buf,rw_offset,length); num_bytes_to_be_written = num_bytes_to_be_written + length; } else{ update_block(array_blockptr[s],(char*)buf,rw_offset,BLOCKSIZE-rw_offset); num_bytes_to_be_written = num_bytes_to_be_written + BLOCKSIZE-rw_offset; } } else if(s==(num_blocks + num_unchanged_blocks-2)){ //last block may be partial if(num_blocks==1){ //special case for one block write. update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,length); num_bytes_to_be_written = num_bytes_to_be_written+length; } else{ update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,(length-(BLOCKSIZE-rw_offset))%BLOCKSIZE); num_bytes_to_be_written = num_bytes_to_be_written+(length-(BLOCKSIZE-rw_offset))%BLOCKSIZE; } } else{ //overwriting a full block update_block(array_blockptr[s],(char *)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,BLOCKSIZE); num_bytes_to_be_written = num_bytes_to_be_written+BLOCKSIZE; } } } //storing the block pointers and put updated_array_blockptr into inode update_inode_pointers(inode_index,updated_array_blockptr,num_blocks+num_unchanged_blocks); int f_num_pointers = get_num_pointers_inode(inode_index); if(f_num_pointers > INODE_POINTERS-1){ //exclude superblock if it is used f_num_pointers--; } int final_inode_pointers[f_num_pointers]; get_pointers(inode_index,final_inode_pointers,f_num_pointers); file_des_t[fileID].rw_pointer+=length; inodes[inode_index].size = return_filesize(inode_index); //writing into disk int inode_number = inode_index; int block_of_inode=inode_number/8+1; char inode_update_buf[BLOCKSIZE]; memset(inode_update_buf,0, BLOCKSIZE); read_blocks(block_of_inode, 1, inode_update_buf); memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE)); write_blocks(block_of_inode, 1, inode_update_buf); write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap); return num_bytes_to_be_written; }
void fd_draw_tinted_scaled_bitmap(FAST_DRAW_CACHE* cache, ALLEGRO_BITMAP* bmp, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh) { int ii; int offx = 0; int offy = 0; ALLEGRO_VERTEX* vertices; int* indices; ALLEGRO_BITMAP* parent = al_get_parent_bitmap(bmp); if(parent == 0) parent = bmp; else al_get_opengl_texture_position(bmp, &offx, &offy); /* HACK */ if(parent != cache->bitmap) fd_flush_cache(cache); cache->bitmap = parent; get_pointers(cache, &vertices, &indices); if(cache->use_indices) { /* 0,3 4 0 1 * o---o o---o * |\ | |\ | * | \ | | \ | * | \| | \| * o---o o---o * 2 1,5 2 3 */ int offi = (cache->size - 1) * 4; indices[0] = offi + 0; indices[1] = offi + 2; indices[2] = offi + 3; indices[3] = offi + 0; indices[4] = offi + 1; indices[5] = offi + 2; vertices[0].x = dx; vertices[0].y = dy; vertices[0].u = sx + offx; vertices[0].v = sy + offy; vertices[1].x = dx + dw; vertices[1].y = dy; vertices[1].u = sx + sw + offx; vertices[1].v = sy + offy; vertices[2].x = dx + dw; vertices[2].y = dy + dh; vertices[2].u = sx + sw + offx; vertices[2].v = sy + sh + offy; vertices[3].x = dx; vertices[3].y = dy + dh; vertices[3].u = sx + offx; vertices[3].v = sy + sh + offy; for(ii = 0; ii < 4; ii++) { vertices[ii].z = 0; vertices[ii].color = tint; } } else { /* 0,3 4 * o---o * |\ | * | \ | * | \| * o---o * 2 1,5 */ vertices[0].x = dx; vertices[0].y = dy; vertices[0].u = sx + offx; vertices[0].v = sy + offy; vertices[1].x = dx + dw; vertices[1].y = dy + dh; vertices[1].u = sx + sw + offx; vertices[1].v = sy + sh + offy; vertices[2].x = dx; vertices[2].y = dy + dh; vertices[2].u = sx + offx; vertices[2].v = sy + sh + offy; vertices[3].x = dx; vertices[3].y = dy; vertices[3].u = sx + offx; vertices[3].v = sy + offy; vertices[4].x = dx + dw; vertices[4].y = dy; vertices[4].u = sx + sw + offx; vertices[4].v = sy + offy; vertices[5].x = dx + dw; vertices[5].y = dy + dh; vertices[5].u = sx + sw + offx; vertices[5].v = sy + sh + offy; for(ii = 0; ii < 6; ii++) { vertices[ii].z = 0; vertices[ii].color = tint; } } }